| | | Gut zu wissen: Hilfreiche Tipps und Tricks aus der Praxis prägnant, und auf den Punkt gebracht für Autodesk Produkte |
Autor
|
Thema: Copy&paste: objekte nach einfügen automatisch markieren (1435 mal gelesen)
|
ritchie1 Mitglied
Beiträge: 25 Registriert: 10.10.2017 AutoCAD 2008, AutoCAD 2011
|
erstellt am: 28. Nov. 2018 22:00 <-- editieren / zitieren --> Unities abgeben:
|
CADmium Moderator Maschinenbaukonstrukteur
Beiträge: 13508 Registriert: 30.11.2003 ACAD 2008 Mechanical
|
erstellt am: 29. Nov. 2018 08:21 <-- editieren / zitieren --> Unities abgeben: Nur für ritchie1
|
rexxitall Mitglied Dipl. -Ing. Bau
Beiträge: 266 Registriert: 07.06.2013 Various: systems, Operating systems, cad systems, cad versions, programming languages.
|
erstellt am: 29. Nov. 2018 12:18 <-- editieren / zitieren --> Unities abgeben: Nur für ritchie1
Falls du keinen Reaktor möchstest (Die bremsen Autocad gehörig aus), kannst du vor der copy aktion die Anzahl der Zeichnungselemente ermitteln. Dann die Copy Aktion anstoßen, alle Elemente deren Index größer als diese ermittelte Anzahl ist, sind deine Kopien. N=thisdrawing.modelspace.count 'hier deine Copy Aktion rein '.... '..... For i = 0 To thisdrawing.modelspace.count - 1 Set entity = thisdrawing.modelspace.ITEM(i) entity.color=acred next Lieben Gruß Thomas ------------------ Wer es nicht versucht, hat schon verlorn Und bei 3 Typos gibts den vierten gratis ! <<< not for sale ! 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: 29. Nov. 2018 14:13 <-- editieren / zitieren --> Unities abgeben: Nur für ritchie1
|
rexxitall Mitglied Dipl. -Ing. Bau
Beiträge: 266 Registriert: 07.06.2013 Various: systems, Operating systems, cad systems, cad versions, programming languages.
|
erstellt am: 30. Nov. 2018 21:45 <-- editieren / zitieren --> Unities abgeben: Nur für ritchie1
|
ritchie1 Mitglied
Beiträge: 25 Registriert: 10.10.2017 AutoCAD 2008, AutoCAD 2011
|
erstellt am: 30. Nov. 2018 22:51 <-- editieren / zitieren --> Unities abgeben:
hallo, vielen dank für eure tips, hat mit ein paar modifikationen funktioniert: wenn ich objekte, die auf einen bestimmten layer liegen, löschen möchte, kann ich nachfolgenden code so direkt nicht ausführen: Set entity = thisdrawing.modelspace.ITEM(i) entity.delete weil nach dem löschen eines objekts die indizes verschoben werden und bei der nächsten schleife eine fehlermeldung kommt. also erstmal die gefundenen entities in eine collection verpacken und anschließend die collection durchlaufen und die objekte löschen. bei blockreferenzen: liegt der block nicht auf den richtigen layer, wird dieser unabhängig von den objekten und deren layer im block gelöscht. jetzt möchte ich aber einzelne objekte der blockref. behalten. das könnte so aussehen: a)die neu eingefügten blockref. rekursiv durchlaufen und alle objekte mit den falschen layern löschen - blockref. bleiben, der inhalt ändert sich aber ... würde sich auf andere blockref. in der zeichnung auswirken dh. man müsste die geänderten blöcke mit neuen namen speichern ... b) die blockref. rekursiv auflösen und dann die objekte auf den falschen layern löschen variante b) wäre mir lieber, aber wie ermittelt man den Index/Handle/ObjectID der objekte welche aus aufgelösten blockreferenz stammen? ev. zuerst den inhalt (=die objekte) des blocks in eine collection packen und danach erst den block auflösen - und das ganze rekursiv falls sich ein weiterer block im block befindet ... was meint ihr? wenn es einfacher geht, bin ganz ohr :-) lg, ritchie 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: 01. Dez. 2018 17:31 <-- editieren / zitieren --> Unities abgeben: Nur für ritchie1
Hallo Ritchie, So ganz klar ist mir nicht was Du machen möchtest aber eine kleine Hilfe kann ich Dir vielleicht geben. Löschen von Objekten: Immer die Liste, egal ob SelectionSet oder Collection von hinten nach vorne durchsuchen. Dann bleiben die Indizes richtig. Zum Auflösen einer Blockreferenz: Pack das Ergebnis in ein Variantarray dann hast Du freie Auswahl. Ein Beispiel dazu gibts in der Autocad-Hilfe . 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: 08. Dez. 2018 16:02 <-- editieren / zitieren --> Unities abgeben: Nur für ritchie1
HI Löschen von ITEM(x) einfach diese entitys in ein neues Array kopieren Pseudocode dim ENTARR() as acadentity n=Item.count redim ENTARR(n) dom c as slong c=0 for i=0 to itemcount if entity is deliquent then set ENTARR(C)=...ITEM(i) c=c+1 next for I=0 to c-1 entarr(i).delete next Dann ist Ruhe Lieben Gruß Thomas ------------------ Wer es nicht versucht, hat schon verlorn Und bei 3 Typos gibts den vierten gratis ! <<< not for sale ! 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: 21. Jan. 2019 06:10 <-- editieren / zitieren --> Unities abgeben: Nur für ritchie1
Schoss mir gearde so durchs Hirn. Ja ne keine Beschädigungen ... Also wenn man auf den Trichter käme die kopierten elemente mit einer unitären Markierung zu versehen . GUIDs bieten sich da an. Handles kannst du für den Zweck vergessen, Kann man eindeutig zwischen den kopierten objekten und den eingefügten unterscheiden. Das ist die hälfte der Miete. Gut man mus irgendwas machen um die kopierten Objekte zu identifizieren.Kommen de aus einer anderen Zeichnung könnte man auch den Filename des Machwerks benutzen. Kommen die aus der gleochen Zeichnung beim Kopiervorgenag GUID erstellen.Nun kann man die Zeichnung nach den XDATAS die wir beim Markieren angeklebt haben selektieren. Stichwort selektionset filter.Nun wird es etwas komplexer, den kram zu selektieren per selektionset ist ja einfach aber vermutlich willst du da blaue Rechtecke dran haben... Geht über nen kleinen Umweg zu Lisp. Sprich man ruft die entsprechnden LISP Funktionen per VBA auf. Nun hast du den Kram nach dem Einfügen markiert. Function Selection_set_activate_by_xdata(ByVal SelectionSet As AcadSelectionSet, Optional APP As String = "SEL", Optional xdata As String, Optional KEEPXDATA As Boolean = False, Optional EXECUTEPSELECT As Boolean = True) As String 'acopm.arx has to be loaded on startup as application 'to set the entitys active you has first usually to use the 'selectionset.select function 'otherwise the selectionset can not be activated 'we fake this by a lisp routine 'you might rewrite it a bit to select any other thing like a array or collection of entitys Dim entity As AcadEntity Dim xdataType() As Integer Dim XDATAVALUE() As Variant Dim XAPPNAME As String Dim ents() As AcadEntity Dim block As AcadBlock Dim c As Long Dim CMD1 As String Dim CMD2 As String Dim N As Long Dim state As Object Dim UCMD As String N = SelectionSet.count 'Save the selectionset and remove old marks On Error Resume Next ' If slectionset Is Nothing Then Exit Function If N = 0 Then Exit Function ReDim ents(SelectionSet.count - 1) ReDim Preserve xdataType(0) ReDim Preserve XDATAVALUE(0): xdataType(0) = 1001: XDATAVALUE(0) = APP For Each entity In SelectionSet entity.SetXData xdataType, XDATAVALUE Set ents(c) = entity c = c + 1 Next selection_previous_delete 'to be sure we kill that last active selectionset cause we will use pselect ! ERR.Clear On Error Resume Next 'Next mark all entitys inside selectionset with a temporary xdata mark ReDim xdataType(1) ReDim XDATAVALUE(1) XAPPNAME = APP xdataType(0) = 1001 XDATAVALUE(0) = XAPPNAME xdataType(1) = 1000 If xdata = "" Then XDATAVALUE(1) = "1" For c = 0 To N ents(c).SetXData xdataType, XDATAVALUE Next On Error GoTo 0 'ensure acad is bored Set state = GetAcadState Do Until state.IsQuiescent DoEvents Set state = GetAcadState CO = CO + 1 If CO = 1000 Then GoTo raus Loop 'use a lisp function to select the desired xdata marked elements, 'cmd1 should be also possible with plain VBA just got the filter not created CMD1 = "(setq #filter (ssget " & Chr(34) & "x" & Chr(34) & "'((-3 (" & Chr(34) & XAPPNAME & Chr(34) & ")))))" & vbCr CMD2 = "_PSELECT" & vbLf & "_P" & vbLf 'activate last selectionset from cmd1 On Error Resume Next thisdrawing.SendCommand CMD1 raus: If KEEPXDATA = False Then ReDim Preserve xdataType(0): ReDim Preserve XDATAVALUE(0): xdataType(0) = 1001: XDATAVALUE(0) = XAPPNAME For c = 0 To N On Error Resume Next ents(c).SetXData xdataType, XDATAVALUE Next End If Selection_set_activate_by_xdata = CMD2 'a textstriong to insert into other commands If EXECUTEPSELECT Then thisdrawing.SendCommand CMD2 End Function ------------------ Wer es nicht versucht, hat schon verlorn Und bei 3 Typos gibts den vierten gratis ! <<< not for sale ! 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: 21. Jan. 2019 06:22 <-- editieren / zitieren --> Unities abgeben: Nur für ritchie1
GUID basteln #If Win64 Then Private Declare PtrSafe Function CoCreateGuid Lib "ole32.dll" (pGuid As GUID) As Long Private Declare PtrSafe Function StringFromGUID2 Lib "ole32.dll" (rguid As Any, ByVal lpstrClsId As Long, ByVal cbMax As Long) As Long Private Declare PtrSafe Function IIDFromString Lib "ole32.dll" (ByVal lpsz As String, ByVal lpiid As Long) As Long #Else Private Declare Function CoCreateGuid Lib "ole32.dll" (pGuid As GUID) As Long Private Declare Function StringFromGUID2 Lib "ole32.dll" (rguid As Any, ByVal lpstrClsId As Long, ByVal cbMax As Long) As Long Private Declare Function IIDFromString Lib "ole32.dll" (ByVal lpsz As String, ByVal lpiid As Long) As Long #End If 'Declare Function CoCreateGuid Lib "OLE32.DLL" (pGuid As GUID) As Long Public Function NewGUID(Optional braces As Boolean = True) As String Dim uid As GUID Dim i As Long CoCreateGuid uid NewGUID = _ hex0(uid.data1, 8) & "-" & _ hex0(uid.data2, 4) & "-" & _ hex0(uid.data3, 4) & "-" & _ hex0(uid.data4(0), 2) & _ hex0(uid.data4(1), 2) & "-" For i = 2 To 7 NewGUID = NewGUID & hex0(uid.data4(i), 2) Next If braces Then NewGUID = "{" & NewGUID & "}" End If End Function
Private Function hex0(N, digits As Integer) As String hex0 = Hex(N) hex0 = String(digits - Len(hex0), "0") & hex0 End Function Die Nummer solla angeblich lt M$ einmalig sein... https://de.wikipedia.org/wiki/Globally_Unique_Identifier Lieben Gruss Thomas
------------------ Wer es nicht versucht, hat schon verlorn Und bei 3 Typos gibts den vierten gratis ! <<< not for sale ! Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Brischke Ehrenmitglied V.I.P. h.c. CAD on demand GmbH
Beiträge: 4171 Registriert: 17.05.2001 ACAD20XX, defun-tools
|
erstellt am: 22. Jan. 2019 09:50 <-- editieren / zitieren --> Unities abgeben: Nur für ritchie1
Hallo, so ganz verstehe ich nicht, weshalb diese Hockstrecksprünge gemacht werden, nur um einen Rektor zu verhindern. Die (aus meiner Sicht einfachste) Lösung besteht aus einer Kombination von 3 Reaktoren. (Ich habe bisher keine Probleme auch nicht mit der Performance mit Events(Reaktoren) - das kenne ich nur aus meiner Lisp-Zeit) CommandWillStart (Paste) {innerhalb dieses Reactors wird ein -> Database.ObjectAppended-Reaktor gestartet, der die der Datenbank hinzugefügten Entities einsammelt -> CommandEnded-Reaktor gestartet } CommandEnded { entfernt daktiviert den Database.ObjectAppended-Reaktor und verarbeitet die eingesammelten Entities } Keine Ahnung, ob ich die Events richtig benannt habe, vom Prinzip her sollte aber in etwa so gehen. Grüße! Holger ------------------ Holger Brischke CAD on demand GmbH Individuelle Lösungen von Heute auf Morgen.
defun-tools Das Download-Portal für AutoCAD-Zusatzprogramme!
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: 22. Jan. 2019 13:26 <-- editieren / zitieren --> Unities abgeben: Nur für ritchie1
Ganz einfach Reaktoren muss man anschubsen. Die Tool Appliction läuft ja dann zwangsweise die ganze Zeit mit. Das will ich einfach nicht Im Gegensatz zu manch einem erstelle ich ja nebenbei auch noch reale Zeichnungen für reale Projekte. Und da ist es ungemein beruhigend, wenn man sicher sein kann, das da nix unerwartet noch mal ebenreinblutgrätscht Habe mal ne Zeichnung mit 500 K Entitys oder mehr.(Weil z.B. mal wieder ein Zulieferer nicht weis wie man mit Acad umgeht und man keine Zeit hat den Müll auch noch aufzuräumen). Sowas kommt bei mir öfter mal vor. (Ich habe nicht umsonst 64 Gig Ram und ein Server Mainboard in meiner Kiste (doppelt breiter Speicher Bus) Und nun code und starte nen Reaktor der auf Linien reagiert. Wenn ich nun den ganzen Kram drehe. Weist was dann abgeht ? (Lageplan in Bauwerksachse drehen z.B.(na klar halb Deutschland drauf nebst Microfeinschraffuren usw)). Sowas passiert meist dann, wenn du eh schon völlig übermüdet bist, es am allerwenigsten brauchen kannst und du schlicht vergessen hast den Automatismus zu deaktivieren. Da ist es allemal besser bei Bedarf eine Zeichnung komplett zu scannen, die gewünschten Änderungen vorzunehmen und den Spuk dann zu beenden. Schönes Beispiel sind Höhenkohten. Klar kann man da nen Reaktor dran klatschen. Oder man verlinkt die beim erstellen in der Zeichnung beim zeichnen und hat nen Update Knopp. Wenn man mit dem zeichnen fertig ist, einmal speichern, UPDATE ALL Knopf drücken und alles ist schick. Nochmal kurz drüberschauen und fertig. Das ist mir "irgendwie" wesentlich lieber. Auch für den Fall der "Last Minute Changes" wo man noch mal eben was überschreibt damit die PDF erst mal rausgeht ... . Lieben Gruß Thomas
------------------ Wer es nicht versucht, hat schon verlorn Und bei 3 Typos gibts den vierten gratis ! <<< not for sale ! Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Brischke Ehrenmitglied V.I.P. h.c. CAD on demand GmbH
Beiträge: 4171 Registriert: 17.05.2001 ACAD20XX, defun-tools
|
erstellt am: 22. Jan. 2019 14:06 <-- editieren / zitieren --> Unities abgeben: Nur für ritchie1
Hallo Thomas, ich kann deine Bedenken, hinsichtlich der Performance bei Objektreaktoren nachvollziehen. Auch die Bedenken hinsichtlich der Commandreaktoren teile ich. Dass man deshalb aber auf diese Möglichkeiten verzichten sollte, diese Ansicht teile ich nicht. Das ist dann eine Sache der Prozessgestaltung. Beispielsweise kann man Zeichnungen, die einen solchen Eventgesteuerten Automatismus unterstützen sollen, nicht-grafisch kennzeichnen, so dass ein Event, das beim Öffnen einer Zeichnung anspringt, die Events für diese Zeichnung aktiviert oder eben auch nicht. Oder man kann, wie im speziellen Fall, den Prozess ja auch so gestalten, dass das CommandWillStart-Event nicht gebraucht wird: Man definiert einfach einen eigenen EinfügeAusZwischenablageBefehl, der dann das CommandEnded-Event genau wie das ObjectAppended-Event aktiviert. In der durch das CommandEnded-Event aufgerufenen Funktion werden beide Events (CommandEnded und ObjectAppended) wieder deaktiviert. Auf diesem Weg kann man ganz bewusst das Manipulieren der eingefügten Objekte handhaben. Die zu manipulierenden Objekte liefert einem das ObjectAppended-Event und die "Hockstrecksprünge" müssen gar nicht gemacht werden.
------------------ Holger Brischke CAD on demand GmbH Individuelle Lösungen von Heute auf Morgen.
defun-tools Das Download-Portal für AutoCAD-Zusatzprogramme!
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: 25. Jan. 2019 12:38 <-- editieren / zitieren --> Unities abgeben: Nur für ritchie1
Hi, Wie schon gewschrieben, für simple Blockeinfügeoperationen ist Event handling overkill. Die kannst per Knopfdruck einsammeln und en Bloc manipulieren. Event gesteuerte Dinge machen nur Sinn wenn die Operationen en Bloc viel zu lange dauern oder man bewusst eine optische Rückmeldung bei der Bearbeitung benötigt. Stahlbeton Biegeformen anpassen. Da willst ja gleich sehen wo die Stangen aus der Schalung guggen Oder halt auch nicht, oder ob sich die Beschriftung überlagert. Für so etwas ist das hilfreich. Nur dann schalt ich es halt an oder aus. Vielleicht einigen wir uns darauf das es Geschmackssache und Anwendungs abhängig nach reiflicher Überlegung ggf. ne Option ist Das debuggen einer solchen Anwendung macht übrigens auch richtig "Freude". Die Erstellung ist auch nicht wirklich trivial. Da kannst graue Haare bei kriegen *lacht* Lieben Gruß Thomas ------------------ Wer es nicht versucht, hat schon verlorn Und bei 3 Typos gibts den vierten gratis ! <<< not for sale ! Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
| Anzeige.:
Anzeige: (Infos zum Werbeplatz >>)
|