| |
| Gut zu wissen: Hilfreiche Tipps und Tricks aus der Praxis prägnant, und auf den Punkt gebracht für Autodesk Produkte |
Autor
|
Thema: Elemente auf Layer durchlaufen und explode'n (2278 mal gelesen)
|
FIippy Mitglied
Beiträge: 6 Registriert: 06.06.2013
|
erstellt am: 07. Jun. 2013 11:00 <-- editieren / zitieren --> Unities abgeben:
Hallo miteinander (nun bin ich auch hoffentlich an der richtigen stelle )! Bin auf dem CAD-Gebiet noch ganz frisch, also entschuldigt evtl. umständlich formulierte Sätze! ^^" Ich habe im Anhang mal eine DWG-Datei als Beispiel angehängt. Mein Ziel worum es mir geht, ist folgendes: Auf einem Layer (in diesem Fall "Raum") liegen Raumstempel welche mir im AutoCAD (verwende "Autodesk AutoCAD 2014") als "AEC_MVBLOCK_REF" angezeigt werden (das müsste dann wohl der ObjectName sein, wenn ich das richtig verstanden habe). Ich würde gerne die Eigenschaften/Attribute dieses Raumstempels auslesen. Allerdings werden mir diese nicht bei den Eigenschaften angezeigt. Was ich nun aber schon herausgefunden habe ist, dass wenn ich dieses Element (Raumstempel) "explode" (in den "Ursprung"), das ich dann schon mal eine "Blockreferenz" bekomme mit mehr Eigenschaften. Wiederhole ich den Schritt noch einmal, bleibt es bei einer "Blockreferenz" habe jetzt aber Attribute die genau das wiedergeben, was ich ursprünglich auslesen möchte. So... Also dach ich mir, VBA kannst'e, also schau ich den Layer durch und wenn ich ein Element auf dem Layer finde, das keine "Blockreferenz" ist, dann explode dieses. Leider bekomme ich immer einen "Laufzeitfehler '438' Objekt unterstützt dies Eigenschaft nicht". Wenn ich den Raumstempel jetzt allerdings in der Zeichnung markiere und dann auf "Ursprung" klicke, funktioniert das wunderbar. Kann mir das einer erklären? Und so sieht mein VBA-Code aus: Code: Sub IterateLayer() Dim eEntity As AcadEntity Dim blockref As AcadBlockReference For Each eEntity In ThisDrawing.ModelSpace If eEntity.Layer = "Raum" Then If Not eEntity.ObjectName = "AcDbBlockReference" Then ' Dim vNewEntity As Variant ' ' vNewEntity = eEntity.Explode eEntity.Explode End If End If Next eEntityEnd Sub
Ich weiß, das wird jetzt nicht die sauberste Lösung sein, daher war meine zweite Idee, den Raumstempel so zu lassen und sozusagen 2 Ebenen in das Element hineinzuschauen, ob es Attribute zum auslesen gibt.. Weiß natürlich nicht ob und wie das im AutoCAD mit VBA möglich ist. Wäre also super dankbar, wenn mir das einer von euch Profi's erklären könnte! Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
xem Mitglied Zeichner
Beiträge: 847 Registriert: 07.08.2008 Software: AutoCAD 2015 - 64bit Windows 10 - 64bit PDFCreator 1.0.2 - 32bit Ghostscript 9.0 - 64bit PDF-XChange Viewer - 64bit GIMP 2.6.8 - 64bit MS Office 2010 - 32bit Opera 12 - 32bit MacroX - 32bit 7-zip - 64bit ----------------------- Hardware: Intel i5 680 3,6GHz @ 4GHz 8GB RAM 1333MHz nVidia GTX 460 1024MB Intel SSD 2.5 80GB X25-M Samsung SyncMaster 245B+ Iiyama ProLite E1900s Logitech mx518 Logitech G11 Roccat Sense Glacier Blue
|
erstellt am: 07. Jun. 2013 12:00 <-- editieren / zitieren --> Unities abgeben: Nur für FIippy
Auf die Schnelle im LISP: Code: (defun c:exb ( / as) ; lokale Variable ;alle Blöcke auf Layer Raum auflösen (setq as (ssget "_X" (list'(-4 . "<OR") '(-4 . "<AND") '(8 . "Raum") '(0 . "AEC_MVBLOCK_REF") '(-4 . "AND>") '(-4 . "OR>") (cons 410 (getvar "CTAB"))))) (if as (command "_explode" as "")) (setq as nil) ; as wird freigeben (princ) (setq as (ssget "_X" (list'(-4 . "<OR") '(-4 . "<AND") '(8 . "Raum") '(0 . "INSERT") '(-4 . "AND>") '(-4 . "OR>") (cons 410 (getvar "CTAB"))))) (if as (command "_explode" as "")) (setq as nil) ; as wird freigeben (princ) )
------------------
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
FIippy Mitglied
Beiträge: 6 Registriert: 06.06.2013
|
erstellt am: 07. Jun. 2013 12:12 <-- editieren / zitieren --> Unities abgeben:
Hallo xem, erst mal danke für deine Bemühung! Aber da ich noch recht unerfahren bin auf dem AutoCAD-Gebiet, hilft mir dein LISP-Code nicht weiter, weil ich ihn von der syntax her nicht verstehe... und wenn ich ehrlich bin, möchte ich mich auch gar nicht zu sehr mit LISP beschäftigen, wenn ich herum komme und es mit VBA lösen kann Kannst du mir auch mit VBA behilflich sein?
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
xem Mitglied Zeichner
Beiträge: 847 Registriert: 07.08.2008 Software: AutoCAD 2015 - 64bit Windows 10 - 64bit PDFCreator 1.0.2 - 32bit Ghostscript 9.0 - 64bit PDF-XChange Viewer - 64bit GIMP 2.6.8 - 64bit MS Office 2010 - 32bit Opera 12 - 32bit MacroX - 32bit 7-zip - 64bit ----------------------- Hardware: Intel i5 680 3,6GHz @ 4GHz 8GB RAM 1333MHz nVidia GTX 460 1024MB Intel SSD 2.5 80GB X25-M Samsung SyncMaster 245B+ Iiyama ProLite E1900s Logitech mx518 Logitech G11 Roccat Sense Glacier Blue
|
erstellt am: 07. Jun. 2013 13:09 <-- editieren / zitieren --> Unities abgeben: Nur für FIippy
|
Andreas Kraus Mitglied Elektrotechniker
Beiträge: 1356 Registriert: 11.01.2006
|
erstellt am: 07. Jun. 2013 16:07 <-- editieren / zitieren --> Unities abgeben: Nur für FIippy
Hallo Flippy, ich glaube es wird beim Durchlaufen ein Objekt gefunden dass die Eigenschaft "explode" nicht hat. Das bekommst du ja auch gemeldet: "Laufzeitfehler '438' Objekt unterstützt dies Eigenschaft nicht". Du musst nur checken ob das aktuelle Objekt zerlegt werden kann oder eben nicht. Wie das in VBA geht kann ich dir nicht sagen, aber das findest du schon raus ob das Objekt diese Eigenschaft hat. ------------------ Geht nicht, gibts nicht Gruß Andreas http://kraus-cad.de Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
FIippy Mitglied
Beiträge: 6 Registriert: 06.06.2013 Autodesk AutoCAD 2014 Win7 x64
|
erstellt am: 07. Jun. 2013 17:17 <-- editieren / zitieren --> Unities abgeben:
Hallo Andreas, also die Fehlermeldung an sich verstehe ich schon, und evtl. schaffe ich auch noch zu prüfen ob das element diesen Befehel kann, was ich aber nicht kapiere ist, es gibt zwei Elemente in der Zeichnung, einmal der "Rahmnen" (...Space) und den "Raumstempel" (AEC_MV_BLOCK...) bei beiden gibt es diesen Fehler, was ja grundsätzlich ok ist, wenn es "von Hand" auch nicht funktionieren würde. Weil wenn ich im AutoCAD das Element markiere und dann auf "Ursprung" klicke, klappt alles wunderbar.... Vielleicht könnte mir jemand bei meinem zweiten "Lösungsweg" einen Anstoß geben... Wie kann ich in ein Element "zwei Ebenen" hineinschauen um zu prüfen ob es Attribute gibt? Schönes Wochenende! Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
KlaK Ehrenmitglied V.I.P. h.c. Dipl. Ing. Vermessung, CAD- und Netz-Admin
Beiträge: 2624 Registriert: 02.05.2006 AutoCAD LandDesktop R2 bis 2004 Civil 3D 2005 - 2022 Plateia, Canalis Visual Basic
|
erstellt am: 07. Jun. 2013 19:42 <-- editieren / zitieren --> Unities abgeben: Nur für FIippy
Hallo Flippy, Willkommen im Forum Leider kann ich die 2014er Zeichnung nicht öffnen, damit ich mir den Block mal ansehen kann. Evtl. kannst Du die zeichnung mal im 2012 Format exportieren? Im Prinzip kannst Du wie folgt vorgehen: 1) Du suchst den Block im Modellspace und holst Dir den Namen dann des darinliegenden Blockes 2) dann durchsuchst Du die Blockssection nach diesen Block - hat dieser die gesuchten Attribute (Stichwort .hasattribute) dann diese auslesen (getattribute) -- Tagstring vergleichen und Textstring auslesen (dazu gibt es hier schon viele Threads) - ist noch ein Block verschachtelt, dann diesen in der Blocksection suchen Hintergrund ist dass dem Raumstempel neben dem Symbol das Du auslesen möchtest vermutlich noch Polylinien zugeordnet sind, dshalb ist das alles so verschachtelt. Grüße Klaus Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
rexxitall Mitglied Dipl. -Ing. Bau
Beiträge: 266 Registriert: 07.06.2013 Various: systems, Operating systems, cad systems, cad versions, programming languages.
|
erstellt am: 07. Jun. 2013 21:12 <-- editieren / zitieren --> Unities abgeben: Nur für FIippy
sub untested dim entity as acadentity dim blockref as acadblockref for each entity in thisdrawing.modelspace if lcase(entity.objectname)="acdbblockreference" then if entity.layer="Raum" then set blockref=entity blockref.explode end if end if next end sub Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
rexxitall Mitglied Dipl. -Ing. Bau
Beiträge: 266 Registriert: 07.06.2013 Various: systems, Operating systems, cad systems, cad versions, programming languages.
|
erstellt am: 07. Jun. 2013 21:21 <-- editieren / zitieren --> Unities abgeben: Nur für FIippy
TESTED AND USED Sub block_set_attribute(blo As AcadBlockReference, tagname, tagvalue) Dim attlist As Variant If blo Is Nothing Then Exit Sub If blo.HasAttributes Then tagname = Trim(UCase(tagname)) attlist = blo.GetAttributes For I = LBound(attlist) To UBound(attlist) ''debug.print "#" & UCase(attlist(i).TagString) & "#", tagname If UCase(attlist(I).TagString) = tagname Or UCase(Trim(attlist(I).TagString)) = tagname & "_001" Then 'On Error Resume Next attlist(I).textstring = "" & tagvalue ' attlist(I).Update ' On Error GoTo 0 Exit Sub End If Next End If End Sub Function block_has_attribute(blo As AcadBlockReference, tagname As String) As Boolean Dim attlist As Variant On Error Resume Next block_has_attribute = False If blo.HasAttributes Then attlist = blo.GetAttributes For I = LBound(attlist) To UBound(attlist) If UCase(attlist(I).TagString) = tagname Or UCase(Trim(attlist(I).TagString)) = tagname & "_001" Then block_has_attribute = True Exit Function End If Next End If End Function Function block_get_attribute(blo As AcadBlockReference, tagname) As String Dim attlist As Variant On Error Resume Next If blo.HasAttributes Then attlist = blo.GetAttributes For I = LBound(attlist) To UBound(attlist) If UCase(attlist(I).TagString) = tagname Or UCase(Trim(attlist(I).TagString)) = tagname & "_001" Then block_get_attribute = attlist(I).textstring Exit Function End If Next End If End Function
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
KlaK Ehrenmitglied V.I.P. h.c. Dipl. Ing. Vermessung, CAD- und Netz-Admin
Beiträge: 2624 Registriert: 02.05.2006 AutoCAD LandDesktop R2 bis 2004 Civil 3D 2005 - 2022 Plateia, Canalis Visual Basic
|
erstellt am: 08. Jun. 2013 10:57 <-- editieren / zitieren --> Unities abgeben: Nur für FIippy
Zitat: Original erstellt von KlaK:
2) dann durchsuchst Du die Blockssection nach diesen Block - hat dieser die gesuchten Attribute (Stichwort .hasattribute) dann diese auslesen (getattribute) -- Tagstring vergleichen und Textstring auslesen (dazu gibt es hier schon viele Threads) - ist noch ein Block verschachtelt, dann diesen in der Blocksection suchen
Als Alternative gäbe es natürlich auch die Möglichkeit eine weitere Kopie dieses Blockes vorübergehend temporär zu erzeugen und diese vor dem Löschen zu untersuchen ... Könnte schneller sein als das Durchlaufen einer (evtl. großen) Blocktabelle. Grüße Klaus Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
rexxitall Mitglied Dipl. -Ing. Bau
Beiträge: 266 Registriert: 07.06.2013 Various: systems, Operating systems, cad systems, cad versions, programming languages.
|
erstellt am: 09. Jun. 2013 20:30 <-- editieren / zitieren --> Unities abgeben: Nur für FIippy
gugg mal mein posting ich benutze dort NICHT einen variant als datentyp. VBA ist objektorientiert, wenn du also eine Methode (explode) von dem element blockreference ausfuehren willst must du eine "variable" (Object) acadblockreference mittels dim erstellen und das generelle entityobject darauf abbilden mit set. Mit anderen worten du setzt den entity pointer auf die Blockreferenz. NUN kannst du alle methoden aufrufen. Das das geklappt hat siehst du daran das NUN auch alle intellisense hilfen verfuegbar sind. Das funktioniert mit allen acad elementtypen. (eigentlich - bei einigen geht nur object als typ und wehe du versorgst soetwas mit der falschen methode - so schnell kannst nicht guggen wie das acad himmelt ) ------------------ wer es nicht versucht, hat schon verlorn Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
FIippy Mitglied
Beiträge: 6 Registriert: 06.06.2013
|
erstellt am: 10. Jun. 2013 10:33 <-- editieren / zitieren --> Unities abgeben:
Hallo! Danke für die Begrüßung und entschuldigt das ich am Wochenende nicht mitgelesen hab ^^ @KlaK: Ich habe die Datei nochmal konvertiert (2010er-Format), falls es noch relevant ist, hoffe ich, das du die Datei jetzt öffnen kannst. @rexxitall: Ich werde mir deinen Code dann noch genauer anschauen, macht aber auf den ersten Blick und wie du beschrieben hast natürlich Sinn.
Auf jeden Fall schon mal Vielen Dank! Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
KlaK Ehrenmitglied V.I.P. h.c. Dipl. Ing. Vermessung, CAD- und Netz-Admin
Beiträge: 2624 Registriert: 02.05.2006 AutoCAD LandDesktop R2 bis 2004 Civil 3D 2005 - 2022 Plateia, Canalis Visual Basic
|
erstellt am: 10. Jun. 2013 13:57 <-- editieren / zitieren --> Unities abgeben: Nur für FIippy
Danke Flippy, Hatte sie schon geöffnet bekommen (aktuelle Bricscadversion) und dabei festgestellt, dass es sich bei dem Block gar nicht um eine "einfache" Blockreferenz handelt, sondern um ein AEC-Objekt (AEC_BlockRef). Dies erklärt warum Du darauf nicht zugreifen konntest. Wenn Du das mal genauer betrachten möchtest, öffne im VBA Editor das Lokal-Fenster. Im Prinzip brauchst Du gar kein großes Programm, eine Sub mit einem Stop-Befehl reicht. Jetzt kannst Du im Lokalfenster das ME-Objekt untersuchen, siehst die beiden AEC-Objekte und die Verschachtelungen. Mal sehen, vielleicht habe ich abends ja Lust auf ein wenig proggen ... (gestern kam ich nicht zu, mal "eben" 1800 km im Auto zurückgelegt )
[Diese Nachricht wurde von KlaK am 10. Jun. 2013 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
rexxitall Mitglied Dipl. -Ing. Bau
Beiträge: 266 Registriert: 07.06.2013 Various: systems, Operating systems, cad systems, cad versions, programming languages.
|
erstellt am: 10. Jun. 2013 21:34 <-- editieren / zitieren --> Unities abgeben: Nur für FIippy
|