Ein paar Worte vorabHome   Letzte MeldungenNews   Index der Kapitel und der besprochenen FunktionenIndex   Wer ich bin, warum ich diese Seiten mache, KontaktImpressum   Ich freue mich über jeden Eintrag im Gästebuch!Gästebuch   Einige Links zu anderen AutoLisp-SeitenLinks   Copyrights und DisclaimerRechts
Hier können die kompletten Seiten als ZIP-File heruntergeladen werden!

Einführung zum Programmieren mit VisualLisp Welcome to...
Das ActiveX-Objektmodell - Grundlage der vl-Programmierung in AutoCAD Das Objekt
Die vla-Funktionen: Viel ActiveX - wenig Dokumentation Knielang
Funktionen für den schnellen Zugriff in VisualLisp Breiter Gürtel
Variants - der Gummi-Datentyp von VBA Damenhandtasche
Collections - VB-Sammelbehälter in VisualLisp Kommste mit rauf?
Das Auffangen von Fehlern in VisualLisp Plumps
Berechnen von Schnittpunkten zwischen Entities mit ActiveX Windschnittig!
Ein erster, einfacher Reaktor, der viel Arbeit sparen kann Faulheit
Importieren von Views aus einer geschlossenen Zeichnung mit DBX Deutsche Bahn


Zum Einsteiger-Tutorial

Zu den Seiten für Fortgeschrittene

Meine Private HP mit Fotos, Gedichten, Musik und Postkartenversand

Mein Online-Lexikon der Fotografie

Mein völlig abgedrehtes Reisebüro










DB steht hier also gar nicht für 'Deutsche Bahn', sondern für 'ObjectDBX', ein Tool, das von AutoDesk vermarktet wird. Es ermöglicht den Zugriff auf ungeöffnete Zeichnungen. Allerdings kann man dieses Toolkit nicht einfach bei AutoDesk kaufen - man kann nur einen Antrag stellen und abwarten, ob man für würdig befunden wird, wenn ich die Dinge richtig sehe.

Gut, wir haben es also nicht, dieses ObjectDBX. Und warum machen wir uns dann Gedanken darüber? Ganz einfach: Wir haben es doch! Schliesslich muss ja AutoCAD eine Zeichnung öffnen können, oder? Der Unterschied ist folgender: Mit dem ObjectDBX-Toolkit können Entwickler auch ohne ein vorhandenes AutoCAD mit Zeichnungen arbeiten - z.B. um einen Viewer zu programmieren usw. Wir müssen uns lediglich darauf beschränken, dass uns die ObjectDBX-Methoden nur dann zur Verfügung stehen, wenn AutoCAD läuft. Das dürfte allerding keine grosse Einschränkung sein...

Dann müssen wir ausserdem noch eine kleine Setup-Arbeit vornehmen, damit das Ganze funktioniert: Wir rufen 'Ausführen' im Startmenü von Windows auf und geben dort folgendes ein: regsvr32 "c:\Programme\AutoCAD 2002 Deu\axDb15.dll". Natürlich muss der angegebene Pfad den tatsächlichen Gegebenheiten angepasst werden. Mit diesem Aufruf melden wir die DLL als ActiveX-Server an und können dann die Funktionalität benutzen.

Der Vorgang lässt sich übrigens jederzeit wieder rückgängig machen: Die Eingabe von regsvr32 /u "c:\Programme\AutoCAD 2002 Deu\axDb15.dll" hebt die Anmeldung wieder auf. Natürlich sind diese Anmeldungen permanent und müssen nicht nach jedem Neustart wiederholt werden.

Als Beispiel für die Arbeit mit einer ungeöffneten Zeichnung habe ich Folgendes ausgewählt: Immer wieder suchen Leute in Diskussionsforen und Newsgroups nach einer Möglichkeit, aus anderen Zeichnungen dort definierte Ausschnitte (Views) zu importieren - diese Möglichkeit besteht über das DesignCenter leider nicht. Die einzige bisherige Möglichkeit war bisher, die Quellzeichnung zu öffnen, die View-Tabelle zu durchforsten und die Views mittels eines komplexeren Programmes in eine Textdatei zu schreiben, um sie von da aus mit einem weiteren Programm in die Zielzeichnung zu importieren.

Hier bietet die ActiveX-Automation deutliche Vorteile: Mit recht wenig Code können wir das Problem lösen, wobei sogar knapp die Hälfte des Codes auf eine Hilfsfunktion entfällt, die wir benötigen, um die Views-Collection der Quellzeichnung in ein Safearray einzulesen. Dieses Array wird von der Methode (vla-CopyObjects) erwartet.

Hier nun zunächst der Funktionscode der Hilfsfunktion:
(defun coll->array(collObject / array i)
  (setq array
    (vlax-make-safearray vlax-vbObject
      (cons 0
        (1-(vla-get-count collObject))
      )
    )
  )
  (setq i 0)
  (vlax-for item collObject
    (vlax-safearray-put-element array i item)
    (setq i(1+ i))
  )
  array
)
                  
Hier passiert nichts Aufregendes: Es wird ein Array erzeugt, und um die Grösse festzulegen, wird die Anzahl der Collection Items mit der Count-Methode ausgelesen (da der Index des Arrays bei 0 beginnt, muss natürlich 1 abgezogen werden). Die Collection wird dann durchgearbeitet und die darin enthaltenen Objekte nacheinander in das Array eingetragen.

Und nun zur Hauptfunktion - zunächst wieder Code, Erklärungen danach:
(defun ImportViews(dwgName / acadObject sourceDocument)
  (vl-load-com)
  (setq acadObject(vlax-get-acad-object))
  (setq activeDocument
    (vla-get-ActiveDocument acadObject)
  )
  (if
    (vl-catch-all-error-p
      (setq sourceDocument
        (vl-catch-all-apply 'vla-GetInterfaceObject
          (list acadObject "ObjectDBX.AxDbDocument")
        )
      )
    )
    (progn
      (princ "\nObjectDBX-Server nicht gefunden")
      (princ)
    )
    (progn
      (if
        (vl-catch-all-error-p
          (vl-catch-all-apply 'vla-open
            (list sourceDocument dwgName)
          )
        )
        (progn
          (princ "\nDatei nicht gefunden")
          (princ)
        )
        (vla-CopyObjects
          sourceDocument
          (coll->array
            (vla-get-views sourceDocument)
          )
          (vla-get-views activeDocument)
        )
      )
      (vlax-release-object sourceDocument)
    )
  )
)
                  
Die Methode (vla-GetInterfaceObject) des Application-Objekts dient zum Verbinden mit ActiveX-Servern. Die type library der geladenen Applikation wird dadurch allerdings noch nicht importiert, dafür wäre (vlax-import-type-library) zuständig. Auf diesen Import können wir in unserem Beispiel allerdings verzichten, da die einzige benötigte Methode open schon zur Verfügung steht.

Es folgt dann ein wenig leicht verschachteltes Error-Handling, um wenigstens die gröbsten Fehler aufzufangen: Das erste (vl-catch-all-apply) kommt zum Tragen, wenn die Funktion ausgeführt wird, aber die axDb15.dll nicht als ActiveX-Server registriert ist. Das zweite ist für den Fall vorgesehen, dass die angegebene Zeichnung nicht gefunden wird.

Sind diese beiden Voraussetzungen aber gegeben, ist das Kopieren denkbar einfach: Mit der Hilfsfunktion wird die Quell-Collection in ein Array umgewandelt, und dann genügt ein Aufruf von (vla-CopyObjects), um die Ausschnitte aus der ungeöffneten Quelldatei in die aktuelle AutoCAD-Zeichnung zu kopieren. Zum Schluss geben wir die Quellzeichnung durch einen Aufruf von (vlax-release-object) wieder frei, und das war's schon.

Grosse Gedanken um den Import müssen wir uns nicht machen - z.B. was passiert, wenn ein Ausschnitt unter gleichem Name schon vorhanden ist, es wird nichts überschrieben. Mit anderen Worten: Es werden nur die Ausschnitte importiert, die in der aktuellen Zeichnung noch nicht vorhanden sind. Bereits existierende Ausschnitte werden nicht angetastet.