| | | Gut zu wissen: Hilfreiche Tipps und Tricks aus der Praxis prägnant, und auf den Punkt gebracht für Autodesk Produkte |
Autor
|
Thema: Tip: Objekte nach SendCommand manipulieren (1902 mal gelesen)
|
CADoktor Mitglied Techniker
Beiträge: 35 Registriert: 29.03.2006
|
erstellt am: 29. Mrz. 2006 16:49 <-- editieren / zitieren --> Unities abgeben:
VBA hat das Problem das nach SendCommand Befehlen wie z.B. DText kein Programmcode mehr in der Prozedur ausgeführt werden kann, da AutoCAD auf Benutzereingaben wartet. Soll nun ein DText mit einer bestimmten expliziten Farbe erstellt werden, kann dies zwar durch Setzen der Systemvariable CECOLOR vor dem Sendcommand erreicht werden. Anschließend könnte in der Ereignisprozedur AcadDocument_EndCommand die Farbe wieder auf ByLayer zurückgesetzt werden. Leider wird AcadDocument_EndCommand aber nur ausgelöst, wenn der Benutzer während des DText Befehls nicht ESC drückt. Und es gibt meines Wissens auch kein Ereignis um das Drücken von ESC auszuwerten. Meine Lösung nutzt deshalb das Ereignis AcadDocument_ObjectAdded. Hier ist der Nachteil, dass das Objekt zu diesem Zeitpunkt noch nicht änderbar ist, da der Befehl noch aktiv ist. Deshal werden die neuen Objekte in einem Stack gespeichert, der anschließend in AcadDocument_EndCommand durchlaufen und wie im beiliegenden Beispiel (Text explizit auf Farbe rot) geändert wird. Wenn´s eine einfachere Lösung gibt, lasst es mich wissen. Folgenden Code im Modul ThisDrawing eingeben ... Dim objStack() As AcadEntity Private Sub AcadDocument_ObjectAdded(ByVal Object As Object) If Object.ObjectName = "AcDbText" Then ReDim Preserve objStack(UBound(objStack) + 1) Set objStack(UBound(objStack)) = Object End If End Sub Private Sub AcadDocument_EndCommand(ByVal CommandName As String) Dim i1 As Integer Dim objText As AcadText If UBound(objStack) > 0 Then If CommandName = "DTEXT" Or CommandName = "TEXT" Then For i1 = 1 To UBound(objStack) Set objText = objStack(i1) With objText .color = vbRed End With Next i1 End If End If End Sub Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
startrek Moderator Architekt
Beiträge: 1361 Registriert: 13.02.2003 .
|
erstellt am: 29. Mrz. 2006 17:59 <-- editieren / zitieren --> Unities abgeben: Nur für CADoktor
Dass sendcommand ein Problemkind ist, ist klar, nicht ganz klar ist mir, warum du Texte ausgerechnet via sendcommand erzeugst. Oder war das nur ein Beispiel? wenn ja dann ists IMHO ein unglückliches;-) Zitat: Original erstellt von CADoktor: Wenn´s eine einfachere Lösung gibt, lasst es mich wissen.
nur ganz grob geschnitzt, vielleicht so? Code:
Sub x() Dim oTxt As AcadText, h#, p, s On Error GoTo ende p = ThisDrawing.Utility.GetPoint(, "Punkt wählen: ") h = CDbl(ThisDrawing.Utility.GetString(0, "Texthöhe: ")) Do s = ThisDrawing.Utility.GetString(1, "Text :") Set oTxt = ThisDrawing.ModelSpace.AddText(s, p, h) oTxt.color = acRed p(1) = p(1) - (1.5 * h) Loop ende: End Sub
Gruss NancyEine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
CADoktor Mitglied Techniker
Beiträge: 35 Registriert: 29.03.2006
|
erstellt am: 29. Mrz. 2006 20:38 <-- editieren / zitieren --> Unities abgeben:
Das mit dem DText ist im Gegenteil ein sehr gutes Beispiel ... Die Variante mit ThisDrawing.ModelSpace.AddText ist ein Beispiel für den üblichen Blindflug beim Arbeiten mit AutoCAD VBA Applikationen. DText zeigt den Text dynamisch bei Erstellen an. Das hat eben den Vorteil, das der Anwender weiss, wann er in die nächste Zeile schalten muss, weil aufgrund angrendzender Objekte kein Platz mehr ist. Ich bin speziell im Bereich Haustechnik tätigt ... Das bedeutet extrem viel Text bei wenig Platz ... deshalb DText als Beispiel. Die beschriebene Variante macht natürlich auch bei anderen Objekten Sinn, wo der Anwender SendCommand nutzen möchte und anschließend noch was an den Objekten ändern will. Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
startrek Moderator Architekt
Beiträge: 1361 Registriert: 13.02.2003 .
|
erstellt am: 29. Mrz. 2006 22:37 <-- editieren / zitieren --> Unities abgeben: Nur für CADoktor
Zitat: Original erstellt von CADoktor: ... wo der Anwender SendCommand nutzen möchte und anschließend noch was an den Objekten ändern will.
Also ich weiss nicht so recht, worauf das ganze hier hinauslaufen soll ... Der Anwender wendet idR von Programmierern vorgefertigte Befehle an, daher der Name Anwender/User/Nutzer;-) Von daher kenne ich keinen Anwender, der sendcommand nutzt, nö der tippt nämlich einfach _dtext in die Commandline ... und acad springt an. Das Ganze von der Programmierperspektive betrachtet, ist es mir nicht klar, warum mit sendcommand? Ich meine, wenn schon programmieren - nix gegen - aber um Krücken wie 'sendcommand' würde ich einen Riesenbogen machen, wenn ich die Möglichkeit dazu habe. Und die Möglichkeit hast Du!;-) Gruss Nancy
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
CADoktor Mitglied Techniker
Beiträge: 35 Registriert: 29.03.2006
|
erstellt am: 30. Mrz. 2006 08:50 <-- editieren / zitieren --> Unities abgeben:
Nochmal ein Versuch der Erklärung ... Das Ziel eine möglichst restriktive Zeichnungsstruktur mit klaren Vorgaben von Layern, Farben, Linientypen etc., die alle in einer Access-Datenbank gespeichert sind. Der Anwender soll nun möglichst wenig Möglichkeiten haben "auszubrechen". Das geht nur, wenn ich Objekte kontrolliere und bei Bedarf manipuliere. Dein Argument ist klar und logisch aber ... Da im TGA Bereich sehr viel Text vorkommt (auch Mehrzeilig) ist die AddText Methode unbrauchbar. Diese war viel leichter zu realisieren und war auch schon in meinem Programm (auf Deine beschriebene Art) vorhanden. Die Anwender haben sich natürlich sofort über den mangelden Komfort beim Eingeben von Texten beschwert. Die Art den Text nicht dynamisch in Bezug zu Zeichnungselementen eintippen zu können und Bedarf einen Zeilenwechsel einzugeben ist ja auch ein tatsächlicher Rückschritt. Deshalb diese Verrenkung. Aber das schöne an dieser Lösung ist, dass sogar Eingaben, die über den DText Befehl auf Befehlzeilenebene gemacht werden abgefangen und ausgewertet werden können. Bei mir werden abhängig davon, auf welchem Layer der Text erstellt wurde, in einer Datenbank nachgeschlagen und die Farben dann explizit angepasst. Warum nun Texte mit expliziten Einstellungen: Die Layerstruktur selbst soll "schlank" bleiben. Deshalb wird Text der klar zu einer bestimmten Haustechnik-Leitung gehört mit auf dem Layer des Mediums platziert. Mein Programm prüft nun, auf welchem Layer der Text erstellt wurde, schlägt in der Datenbank nach, welches Gewerk der Leitungslayer ist (z.B. Heizung), ermittelt dann die Textfarbe für Heizung und ändert den Text nachträglich ab. Das gleiche gilt für Symbole (Blöcke), die ich ebenfalls sichtbar einfügen will und nicht mit .InsertBlock Wer mit .AddText und .InsertBlock klarkommt und den "Blindflug" akzeptiert, da er beim Punkt wählen das entsprechende Objekt nicht sieht ist das klar die programmtechnisch bessere Lösung. Ich habe dieses Thema nur erstellt, da immer wieder mal der Wunsch für eine SendCommand Lösung besteht und bisher nix entsprechendes hier im Forum zu finden war. Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Stelli1 Moderator Verm.-Ing.
Beiträge: 1521 Registriert: 17.08.2005 Map 2000-2014, Rasterdesign, MapGuide, Autodesk Topobase, VS6, VS.net 2013
|
erstellt am: 30. Mrz. 2006 09:12 <-- editieren / zitieren --> Unities abgeben: Nur für CADoktor
Hallo CADoktor, erstmal noch nachträglich herzlich willkommen im VBA Forum. Die vorgetragenden Gesichtspunkte sind eigentlich recht interessant und zeigen gute Möglichkeiten auf VBA in Verbindung mit User Interaktionen zu verwenden. Es kommt jedoch auf die Aufgabenstellung an. Die meisten hier verwenden VBA um bestehende Elemente zu manipulieren oder aus vorhandenen Daten neue abzuleiten. Bei dieser Aufgabe ist die Verwendung von Sendcommand ein Risiko, da der Ablauf des Programmes unter Umständen gefährdet wird. Es besteht auch die Gefahr, das mit neuen Versionen von AutoCAD ander "Tastenfolgen" notwendig sind. Dann ist es sehr schwer diese in ein vorhandenes Programm zu übernehmen. Auf jedenfall ist es schön zu wissen, das wir in Zukunft jemanden haben den wir mit Fragen bezüglich Sendcommand und der "Drawing Events" löchern können. Stelli ------------------ Warum lisp'eln wenn's auch anders geht. www.ib-stelberg.de Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
CADoktor Mitglied Techniker
Beiträge: 35 Registriert: 29.03.2006
|
erstellt am: 30. Mrz. 2006 09:46 <-- editieren / zitieren --> Unities abgeben:
Naja ... ob ich da Experte bin weiss ich nicht. Ich habe erst vor ein paar Monaten angefangen mich mit AutoCAD VBA intensiver zu beschäftigen. Ziel ist eine Nachfolger für meine Applikation TGA2001, das ich mal für AutoCAD LT erstellt habe. Da LT nicht wirklich programmierbar ist, muss man sich dort besonders mit MenüScript, Diesel und Scripts rumschlagen. Da meine Ansprüche nun doch gestiegen sind und ich etwas mit Datenbankanbindung erstellen wollte, versuche ich es nun mit VB bzw. VBA. Nach einigen Versuchen mit LTCustomizer (japanisches ActiveX Control eines Japanischen Programmierers zum Programmieren von AutoCAD LT über VB) bin ich nun doch bei VBA gelandet, da hier doch einiges leicher realisierbar ist. Nervig ist nur, das VBA Forms im Vergleich zu VB sehr eingeschränkt sind (z.B fehlt der Index bei den Steuerelementen). Aber ich werde mich in der nächsten Zeit hier mal etwas stärker einbringen, da ich das Forum hier als eines der sinnvollsten erachte. Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
fuchsi Mitglied Programmierer c#.net Datawarehouse
Beiträge: 1201 Registriert: 14.10.2003 AutoCad Version 2012 deu/enu <P>Windows 7 64bit
|
erstellt am: 30. Mrz. 2006 16:10 <-- editieren / zitieren --> Unities abgeben: Nur für CADoktor
leider hat VBA nicht die Evenst inkludiert, wie Lisp In Lisp gibt es sehr wohl den Reaktor :vlr-commandCancelled Ich habe mir sowas ähnliches in Lisp realisiert, im Reaktor :vlr-CommandWillStart merke ich mir ein einer globalen variable mittels (entlast) das letzte Objekt in der Datenbank. Nach dem :vlr-commandCancelled bzw :vlr-commandEnded ducrchsuche ich mit (entnext) alle dazugekommenen Elemente, und kann diese je nach Elementtyp verschieden behandeln. ------------------ Ing. Anton Fuchs WWW.FFZELL.AT.TC Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
CADoktor Mitglied Techniker
Beiträge: 35 Registriert: 29.03.2006
|
erstellt am: 30. Mrz. 2006 16:16 <-- editieren / zitieren --> Unities abgeben:
|
AandreasH Mitglied EDV Techniker
Beiträge: 18 Registriert: 08.01.2008 Autocad 2004 Civil3D 2008 VBA
|
erstellt am: 15. Jan. 2008 08:57 <-- editieren / zitieren --> Unities abgeben: Nur für CADoktor
Hallo, muss schon wieder einen alten Beitrag ausgraben. Habe hier das gleiche Probelm. Ich möchte einen Block sichtbar einfügen. Ich werde aus dem Beitrag nicht ganz schlau. Wie löst man soetwas nun wirklich? Grüsse Andreas Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
| Anzeige.:
Anzeige: (Infos zum Werbeplatz >>)
|