| |  | Gut zu wissen: Hilfreiche Tipps und Tricks aus der Praxis prägnant, und auf den Punkt gebracht für Autodesk Produkte | | |  | PNY präsentiert die PRO Elite™ High Endurance microSD-Flash-Speicherkarten für Videoüberwachung und kontinuierliche Aufzeichnung, eine Pressemitteilung
|
Autor
|
Thema: Block.delete funktioniert nicht immer (2610 mal gelesen)
|
Christian Blei Mitglied
 
 Beiträge: 124 Registriert: 23.06.2008 Thinkpad T60p, 4GB XP,Autocad 2010, ProStructures V8i 2, VBA, VB.NET,
|
erstellt am: 27. Jan. 2010 12:59 <-- editieren / zitieren --> Unities abgeben:         
Hallo! ich lösche in einer Zeichnung Blöcke, nachdem ich geprüft habe, dass es keine zugehörigen Blockreferenzen gibt. Das funktioniert nicht immer warum? (die Blöcke beziehen sich auf jeweils ein Entity und haben deswegen den Namen Entity.Handle.1, Entr.Handle.2 etc.) (die Blöcke, die mit dem Code nicht gelöscht werden, lassen sich aber über die Konsole löschen.) Sub purge_BlockDefs(ByRef Handle As String) Dim Block As AcadBlock Dim Ent As AcadEntity Dim BlockReference As AcadBlockReference Dim IsInserted As Boolean
For Each Block In ThisDrawing.Blocks If Left(Block.Name, Len(Handle)) = Handle Then IsInserted = False For Each Ent In ThisDrawing.ModelSpace If TypeOf Ent Is AcadBlockReference Then Set BlockReference = Ent If BlockReference.Name = Block.Name Then IsInserted = True End If End If Next If inserted = False Then On Error Resume Next Block.Delete End If End If Next
End Sub Christian Blei Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 27. Jan. 2010 13:02 <-- editieren / zitieren -->
Hi, hast Du auch eine Zeichnung, in der das auftritt? - alfred - ------------------ www.hollaus.at |
Brischke Ehrenmitglied V.I.P. h.c. CAD on demand GmbH

 Beiträge: 4191 Registriert: 17.05.2001 ACAD20XX, defun-tools
|
erstellt am: 27. Jan. 2010 13:23 <-- editieren / zitieren --> Unities abgeben:          Nur für Christian Blei
Hallo, lässt sich denn der wundersame Block bereinigen? Falls das ebenfalls nicht möglich ist, dann existiert eine Blockreferenz in irgendeinem Block (verschachtelt). Wenn ich deinen Code richtig interpretiere, dann prüfst du nur das Vorhandensein von Blockreferenzen im Modell-Bereich. Du musst diese Prüfung sowohl auf die Objekte in den verschiedenen Layouts als auch den (wie oben erwähnt) anderen Blockdefinitionen vornehmen, um sicher zu gehen, dass dieser Block wirklich nirgends weiter referenziert ist. Warum bereinigst du nicht einfach? Bei Fragen ... Grüße Holger ------------------ Holger Brischke CAD on demand GmbH Individuelle Lösungen von Heute auf Morgen. Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Christian Blei Mitglied
 
 Beiträge: 124 Registriert: 23.06.2008 Thinkpad T60p, 4GB XP,Autocad 2010, ProStructures V8i 2, VBA, VB.NET,
|
erstellt am: 27. Jan. 2010 13:31 <-- editieren / zitieren --> Unities abgeben:         
|
Christian Blei Mitglied
 
 Beiträge: 124 Registriert: 23.06.2008 Thinkpad T60p, 4GB XP,Autocad 2010, ProStructures V8i 2, VBA, VB.NET,
|
erstellt am: 27. Jan. 2010 14:01 <-- editieren / zitieren --> Unities abgeben:         
Hallo Herr Brischke, (die Blöcke, die mit dem Code nicht gelöscht werden, lassen sich aber über die Konsole löschen.) Purge funktioniert also. Da ich die Blöcke und Blockreferenzen selbst erzeuge, habe ich bis jetzt nur da gesucht, wo ich sie auch erzeugt habe. Aber ich werde ihren Hinweissen nachgehen. Gruss, Christian blei Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 27. Jan. 2010 14:16 <-- editieren / zitieren -->
Hi Christian, Du hast an den Elementen entweder XRecords und/oder auch EED's dran hängen, die auf die Blockreferenz verweisen, zumindest scheint es so. Auf die schnelle hab ich die Referenzierung nicht gefunden. Ich hab in Deiner DWG alles rausgelöscht, ausser ein LoftedSurface (Handle AE13), es ist nichts anders mehr in der DWG, nicht im Modellbereich, nicht in Layouts. ==> Durchlauf hängt mit Fehler (wenn Du 'On Error Resume Next' rausnimmst). Löscht Du aber alle Elemente auf dem Layer AFP_Sec_Line, dann funktioniert Dein Tool. Lass mal wissen, ob Dir dieser Hinweis schon mal auf die Sprünge hilft, wenn nicht, lass es mich auch wissen. Zum Code: - ein 'Exit For' wenn Du schon die erste Blockreferenz gefunden hast, hilft geschwindigkeitsmäßig - ein SelectionSet bilden (0 . "INSERT") (2 . "4231.1") gibt Dir auch Elemente retour, die nicht in Modellbereich liegen würden und könnte bei großen Geometrien schneller sein als durchscannen. - würdest Du das mit dotNET machen, dann brauchst Du gar nicht durchscannen, denn der BlockTableRecord hat eine Eigenschaft, die Dir angibt, wie oft die Blockdefinition in der Zeichnung referenziert ist. - alfred - ------------------ www.hollaus.at |
Christian Blei Mitglied
 
 Beiträge: 124 Registriert: 23.06.2008 Thinkpad T60p, 4GB XP,Autocad 2010, ProStructures V8i 2, VBA, VB.NET,
|
erstellt am: 27. Jan. 2010 22:49 <-- editieren / zitieren --> Unities abgeben:         
Hi Alfred, danke für die Tipps. "Exit for" ist mir durchgegangen, die Mächtigkeit der Selectionsets ist mir häufig nicht so bewusst. Aber wegen des eigentlichen Problems: Was mich wundert, ist, dass ich, wenn ich den Debugger laufen lasse und am Ende der Sub abbreche, anschliessend den nichtgelöschten Block problemslos purgen kann. Das Problem ist auch nicht reproduzierbar: Je nach dem mit welchem Selectionset ich arbeite, habe ich es oder nicht. Kann es sein, dass die Database korrupt wird? Die Sub ist Teil eines Moduls mit ein paar Hundert Zeilen, das will ich nicht unbedingt posten. Warum meinst du, das die XData ein Problem darstellen könnten? Ich habe darin nur Handlebezüge als Strings. Ich bin die nächsten Tage unterwegs, habe aber meine Kiste dabei und werde weiter schauen. In jedem Fall poste ich, was aus dem Problem geworden ist. Gruss, Christian Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 27. Jan. 2010 22:56 <-- editieren / zitieren -->
Hi, >> Was mich wundert, ist, dass ich, wenn ich den Debugger laufen lasse und am Ende der Sub abbreche, >> anschliessend den nichtgelöschten Block problemslos purgen kann Das konnte ich auch reproduzieren (mit VBA-Code: nein / mit Befehl _purge: funkt). >> Warum meinst du, das die XData ein Problem darstellen könnten? Ich habe darin nur Handlebezüge als Strings
Darum hab ich auch die Formulierung 'zumindest scheint es so' verwendet. Ich sah, dass in den EED's Handles mit DXFCode 1000 und nicht mit 1005 gespeichert sind. Da Du aber vielleicht den Zusammenhang in Deinem Programm kennst (zwischen den Elementen auf dem Layer AFP_Sec_Line und diesem einen Blocktyp, findest Du ev. dieses mit meinem Hinweis schneller als ich, ich müsste jetzt die ganze Zeichnung durchforsten, wo sonst noch EED's herumkursieren und was wie gegenseitig referenziert ist. Gibt es aus Deiner Sicht einen Zusammenhang oder siehst Du keinen? - alfred - ------------------ www.hollaus.at |
Christian Blei Mitglied
 
 Beiträge: 124 Registriert: 23.06.2008 Thinkpad T60p, 4GB XP,Autocad 2010, ProStructures V8i 2, VBA, VB.NET,
|
erstellt am: 28. Jan. 2010 00:14 <-- editieren / zitieren --> Unities abgeben:         
Hi Alfred, Natascha meint ich soll mal aufhören. Ich muss auch morgen 6.30 los. Ehrlich gesagt, keine Ahnung gerade. Was ich ja mache in dem Modul, ist, ich lösche die vorhandene Blockreferenz mit Namen "X", lösche dann den Block mit Namen "X". (Was nicht funzt). Eventuell bilde ich dann Block mit Namen "X" neu und füge eine Blockreferenz mit Namen "X" ein. Ich habe mich auch schon gefragt, ob die Database nach dem Löschen der Blockreferenzen abgedated wird oder ob es da ein Problem geben kann. Ich versuch das Ganze einzugrenzen. Ich hoffe auch, dass vba bald bei mir Vergangenheit ist. Gute nacht (0.13!) Christian Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 28. Jan. 2010 00:23 <-- editieren / zitieren -->
Hi, >> Ich habe mich auch schon gefragt, ob die Database nach dem Löschen der Blockreferenzen abgedated wird Mit VBA ja, da es nicht TransAction-basierend arbeitet, wird jede Modifikation sofort an der Datenbank durchgeführt. >> Was ich ja mache in dem Modul, ist, ich lösche die vorhandene Blockreferenz mit Namen "X", >> lösche dann den Block mit Namen "X". (Was nicht funzt)
Das versteh ich, ich hätte nur gehofft, dass Dir ein Zusammenhang zwischen den Volumenkörpern auf diesem Layer und den (gelöschten) Blockreferenzen einfällt, die Du in Deiner App oder die ProSteel setzt. Der AutoCAD-Purge-Befehl könnte vorher noch einige Bereinigungen durchführen, die in VBA mit normalem Blockdefinition-Löschen eben nicht angewendet wird. Wenn Du Zusammenhänge kennst, dann lass mich diese wissen, dass ich gezielter suchen kann. EED-Daten (oder auch ev. XRecords) einfach so Blind durch die Zeichnung verfolgen ist ohne diese Kenntnisse einigermaßen aufwendig. >> Natascha meint ich soll mal aufhören. Ich muss auch morgen 6.30 los
Na dann schöne Grüße unbekannterweise, die Abfahrtszeit gilt morgen auch für mich und ich bin auch noch MAXIMAL 5 MINUTEN (EDV-Minuten ) beschäftigt. - alfred - ------------------ www.hollaus.at |
Christian Blei Mitglied
 
 Beiträge: 124 Registriert: 23.06.2008 Thinkpad T60p, 4GB XP,Autocad 2010, ProStructures V8i 2, VBA, VB.NET,
|
erstellt am: 28. Jan. 2010 06:16 <-- editieren / zitieren --> Unities abgeben:         
Hi Alfred, was ich ja mit den gelöschten Blockreferenzen gemacht habe, ist, im angehängten .NEt Teil des Codes IDs geswappt. Aber da sehe ich jetzt auch keinen Zusammenhang, oder können da noch "Spuren" da sein? Vor Allem, da ja die Handles mit Groupcode 1000 gspeichert sind. Ich habe im Moment wirklich keine Idee, weshalb die XData Probleme bereiten sollten. naja, muss mal zuklappen Christian Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Christian Blei Mitglied
 
 Beiträge: 124 Registriert: 23.06.2008 Thinkpad T60p, 4GB XP,Autocad 2010, ProStructures V8i 2, VBA, VB.NET,
|
erstellt am: 29. Jan. 2010 09:24 <-- editieren / zitieren --> Unities abgeben:         
Hi Alfred, ich weiss immer noch nicht, was da los ist, aber ich weiss, wie es anfängt. Am Ende meines VBa Befehls bilde ich ein SS, das ich mir im danach aufgerufenen .Net Teil über TAcadDoc.Editor.SelectPrevious hole. Wenn ich beim Testen verrsehentlich mit rechter Maustaste... den .Net befehl nochmal starte, erzeuge ich Mist. Welche, hast du da eine Idee? Ich will jetzt erstmal die Objekte im SS in Vba markieren, und die Markierung in .Net Am einer der Sub wieder aufheben, um die Entites im SS in der .Net sub bei einem versehentlichen zweiten Durchlauf prüfen und ausfiltern zu können. Ich will dazu eine XData anhängen mit einem Bool (isValid). Hast du eine bessere Idee dazu? Gruss, Christian Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 29. Jan. 2010 12:39 <-- editieren / zitieren -->
Hi, >> danach aufgerufenen .Net Teil über TAcadDoc.Editor.SelectPrevious hole. >> Wenn ich beim Testen verrsehentlich mit rechter Maustaste... den .Net befehl nochmal starte kommt mir ein wenig quer vor, denn ich konnte Dein Problem direkt reproduzieren, ohne dass zuvor ein SelectionSet (oder Dein dotNET-Teil) aktiv geworden wäre. Zumindest kann's damit mal nicht vom Ablauf abhängen. Wenn aber Dein zweiter Aufruf der dotNET-Sub etwas in die Elemente hineinschreibt ==> dann könnte ich es mir vorstellen. Da wäre wichtig zu wissen, was hineingeschrieben wird. >> Ich will jetzt erstmal die Objekte im SS in Vba markieren, und die Markierung >> in .Net Am einer der Sub wieder aufheben, um die Entites im SS in der .Net sub >> bei einem versehentlichen zweiten Durchlauf prüfen und ausfiltern zu können
Wenn Du am Ende einfach das Previous-SelectionSet leerst (Elemente aus den SelSet raus), dann würdest Du beim zweiten Aufruf prüfen, ob im Prev-SelSet Elemente enthalten sind, wenn nein, dann cancel. >> Ich will dazu eine XData anhängen mit einem Bool (isValid)
Wenn es nur temporär notwendig ist (eben um zu wissen, ob das Element schon behandelt wurde), dann ist schreiben der EED-Daten Käse, kostet zu viel Zeit und vor allem musst Du diese dann auch vor dem nächsten gewollten Aufruf auch wieder zurücksetzten (kostet nochmals Zeit). Du kannst ja über Events mitprotokolieren, welche ObjID modifiziert wurde und diese merkst Du Dir während dieses Ablaufs bis diese Liste im Speicher nicht mehr gehalten werden muss. HTH, - alfred - ------------------ www.hollaus.at |
Christian Blei Mitglied
 
 Beiträge: 124 Registriert: 23.06.2008 Thinkpad T60p, 4GB XP,Autocad 2010, ProStructures V8i 2, VBA, VB.NET,
|
erstellt am: 31. Jan. 2010 16:55 <-- editieren / zitieren --> Unities abgeben:         
Hi Alfred, >>kommt mir ein wenig quer vor, denn ich konnte Dein Problem direkt reproduzieren, ohne dass zuvor ein SelectionSet (oder Dein dotNET-Teil) aktiv geworden wäre. Zumindest kann's damit mal nicht vom Ablauf abhängen.<< Die Zeichnung, die ich dir geschickt habe, hat ja schon die Macken..... >>Wenn aber Dein zweiter Aufruf der dotNET-Sub etwas in die Elemente hineinschreibt ==> dann könnte ich es mir vorstellen. Da wäre wichtig zu wissen, was hineingeschrieben wird.<<
Ich muss das nochmals durchschauen. Aber ich speichere nur Handles als Strings, da sehe ich kein Problem. Mir ist halt aufgefallen, dass die Probleme mA dann entstehen, wenn der .Net Teil versehentlich nochmal läuft. Was ich zusätzlich im .Net Teil mache, ich swape Ids. >>Der AutoCAD-Purge-Befehl könnte vorher noch einige Bereinigungen durchführen, die in VBA mit normalem Blockdefinition-Löschen eben nicht angewendet wird.<<
Was für Bereinigungen könnten denn das sein? >>Wenn es nur temporär notwendig ist (eben um zu wissen, ob das Element schon behandelt wurde), dann ist schreiben der EED-Daten Käse,<<
ok, ist klar.... >>Wenn Du am Ende einfach das Previous-SelectionSet leerst (Elemente aus den SelSet raus), dann würdest Du beim zweiten Aufruf prüfen, ob im Prev-SelSet Elemente enthalten sind, wenn nein, dann cancel.<<
da kommen jetzt meine Fragen. Wie remove ich Elemente aus einem SelSet? In .Net habe ich da Nichts gefunden, ich habe dann versucht über Com, also Interop, AutocadSelectionset zu gehen, mit Dim tComSelectionset as interop.AcadSelectionset=Ctype(....Selectprevious.value,Interop.AcadSelectionset) bekomme aber die Meldung, dass sich ein EditorInput.SelectionsetfullyMarshalled nicht casten lässt. Wie erfolgt in .Net der Zugriff auf die max. 128 Selectionsets in einer Zeichnung überhaupt? Wo kann ich den was SSs angeht (für .net) am Besten recherchieren? Ich habe statt XData anzuhängen die Liniestärke der Objekte im SelectPrevious verändert und setze diese in im .Net Teil wieder auf byLayer, besser als XData, aber natürlich nicht so schön wie Selectionset.remove (ent) oder Selectionset.clear.
Gruss, Christian Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 31. Jan. 2010 17:36 <-- editieren / zitieren -->
Hi, >> ich swape Ids Ich nehme an, dass die ObjectID's zu tauschen eine ziemliche 'Hinterrücks-Aktion' ist, auch innerhalb von AutoCAD. Da wäre schon mal ein Ansatz oder zumindest ein Unsicherheitsfaktor. Hängt natürlich davon ab, was mit den Elementen passiert, deren ObjectID Du ausgetauscht hast (sprich die dann von Datenbank getauscht zu aus der Datenbank draussen ==> brav .Dispose gemacht?). >> Wie remove ich Elemente aus einem SelSet
ohne jetzt nachsehen zu können, es sollte ein .Clear geben und damit sollte das SelectionSet geleert sein. Im letzten Absatz hast Du ja darauf verwiesen, funktionierts nicht? >> Ich habe statt XData anzuhängen die Liniestärke der Objekte im SelectPrevious verändert
Dann macht das AutoCAD am Ende Deiner Funktion auch noch ein REGEN jedes Objekts. Wenn es viele Objekte sind, dann oops. >> dass sich ein EditorInput.SelectionsetfullyMarshalled nicht casten lässt
Wundert mich! Du hast aber jederzeit die Möglichkeit, Dir eine eigene ObjectIDCollection anzulegen und dort die ObjectID's zu sammeln, damit brauchst Du das SelectionSet nicht mehr. - alfred - ------------------ www.hollaus.at |
Christian Blei Mitglied
 
 Beiträge: 124 Registriert: 23.06.2008 Thinkpad T60p, 4GB XP,Autocad 2010, ProStructures V8i 2, VBA, VB.NET,
|
erstellt am: 31. Jan. 2010 17:49 <-- editieren / zitieren --> Unities abgeben:         
Hi Alfred, >> ohne jetzt nachsehen zu können, es sollte ein .Clear geben und damit sollte das SelectionSet geleert sein. Im letzten Absatz hast Du ja darauf verwiesen, funktionierts nicht? << Gibt es in .Net nicht. Auch keon remove. Zumindesten in Autocad 2009. Rein gefühlt, die SS haben in .Net nicht die Bedeutung wie in lisp oder Vba. Im Developer's Guide Introduction schreibt Autodesk vom Mergen von Selectionsets indem man die ObjectIds in Collections zusammenführt.... TonyT schreibt "remove of Entites" aus SS geht nicht, "adding" geht. Meine Probleme kommen ja daher, das ich das SelectionPrevious benutze um im .Net Teil meines Codes mir die Entites zu holen, die ich bearbeiten will. Am Schluss meines vba Codes bilde ich deswegen ein SS. Jetzt könnte ich in .net am Ende ein (Dummy)-SS bilden, mit einer entsprechenden Filterung, die mir bei select kein Object holt, und damit in der zweiten Runden ein PreviousSelect bekommen, das keine Objekte hat. Was Anderes fällt mir da gerade nicht ein. >>Ich nehme an, dass die ObjectID's zu tauschen eine ziemliche 'Hinterrücks-Aktion' ist, auch innerhalb von AutoCAD. Da wäre schon mal ein Ansatz oder zumindest ein Unsicherheitsfaktor. Hängt natürlich davon ab, was mit den Elementen passiert, deren ObjectID Du ausgetauscht hast (sprich die dann von Datenbank getauscht zu aus der Datenbank draussen ==> brav .Dispose gemacht?).<<
Das werde ich jetzt checken. Ich tippe, dass das die Ursache ist. Gruss, Christian
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
| Anzeige.:
Anzeige: (Infos zum Werbeplatz >>)
 |