AutoLISP: The Complete Guide — Chapter 16 / 16

ActiveX Interoperability

AutoLISP, through Visual LISP extensions, can communicate with any application that supports ActiveX/COM (Component Object Model). The most common example is interacting with Microsoft Excel to export data or generate reports, but the same principle applies to Word, Outlook, or any other application exposing a COM interface.

Important: ActiveX communication only works on Windows. Mac versions of AutoCAD do not support Visual LISP ActiveX.

The COM Model in Brief

The COM model is based on three concepts:

  • Objects: software entities that expose functionality (an Excel workbook, a worksheet, a cell)
  • Properties: values that can be read or modified on an object (a cell's value, the application's visibility)
  • Methods: actions that can be performed on an object (adding a workbook, saving a file)

From AutoLISP, these objects are manipulated using the vlax-* functions.

Key Functions

Function Purpose
vlax-get-or-create-object Connect to an application (launches it if necessary)
vlax-get-object Connect to an application that is already running
vlax-get-property Read a property of a COM object
vlax-put-property Modify a property of a COM object
vlax-invoke-method Call a method on a COM object
vlax-release-object Release a COM object (prevents memory leaks)

Connecting to an Application

;; Launch Excel (or connect to an existing instance)
(setq excel (vlax-get-or-create-object "Excel.Application"))

;; Connect only if Excel is already open (returns nil otherwise)
(setq excel (vlax-get-object "Excel.Application"))

Common COM application names:

Application COM Identifier
Microsoft Excel "Excel.Application"
Microsoft Word "Word.Application"
Microsoft Outlook "Outlook.Application"

COM applications expose an object hierarchy. For Excel, the chain is: ApplicationWorkbooksWorkbookWorksheetsWorksheetCellsCell. You navigate from one level to the next using vlax-get-property:

(setq workbooks (vlax-get-property excel 'Workbooks))
(setq workbook (vlax-invoke-method workbooks 'Add))
(setq sheet (vlax-get-property workbook 'ActiveSheet))

Simplifying Cell Access

The code to write to an Excel cell is quite verbose with raw vlax-* functions. You can factor it into utility functions:

(defun write-cell (sheet row column value / cell)
  (setq cell
    (vlax-get-property
      (vlax-get-property sheet 'Cells)
      'Item row column
    )
  )
  (vlax-put-property cell 'Value value)
)

(defun read-cell (sheet row column / cell)
  (setq cell
    (vlax-get-property
      (vlax-get-property sheet 'Cells)
      'Item row column
    )
  )
  (vlax-get-property cell 'Value)
)

Usage:

(write-cell sheet 1 1 "No.")
(write-cell sheet 1 2 "Length")
(write-cell sheet 2 1 1)
(write-cell sheet 2 2 42.5)

(read-cell sheet 2 2)  ; → 42.5

Full Example: Exporting a Quantity Takeoff to Excel

This program selects all lines in the drawing, calculates their total length, and exports the details to an Excel spreadsheet:

(defun c:takeoff-excel (/ selection-set index entity data start-point end-point
                          length excel workbooks workbook sheet
                          excel-row total-length)
  ;; Select all lines
  (setq selection-set (ssget "_X" '((0 . "LINE"))))

  (if (null selection-set)
    (progn (princ "\nNo lines found.") (princ) (exit))
  )

  ;; Launch Excel (or connect to an existing instance)
  (setq excel (vlax-get-or-create-object "Excel.Application"))

  ;; Make Excel visible
  (vlax-put-property excel 'Visible :vlax-true)

  ;; Create a new workbook
  (setq workbooks (vlax-get-property excel 'Workbooks))
  (setq workbook (vlax-invoke-method workbooks 'Add))
  (setq sheet (vlax-get-property workbook 'ActiveSheet))

  ;; Write headers
  (write-cell sheet 1 1 "No.")
  (write-cell sheet 1 2 "X1")
  (write-cell sheet 1 3 "Y1")
  (write-cell sheet 1 4 "X2")
  (write-cell sheet 1 5 "Y2")
  (write-cell sheet 1 6 "Length")

  ;; Iterate through the drawing's lines
  (setq index 0)
  (setq excel-row 2)
  (setq total-length 0.0)

  (repeat (sslength selection-set)
    (setq entity (ssname selection-set index))
    (setq data (entget entity))
    (setq start-point (cdr (assoc 10 data)))
    (setq end-point (cdr (assoc 11 data)))

    ;; Calculate the length
    (setq length (distance start-point end-point))
    (setq total-length (+ total-length length))

    ;; Write to Excel
    (write-cell sheet excel-row 1 (1+ index))
    (write-cell sheet excel-row 2 (nth 0 start-point))
    (write-cell sheet excel-row 3 (nth 1 start-point))
    (write-cell sheet excel-row 4 (nth 0 end-point))
    (write-cell sheet excel-row 5 (nth 1 end-point))
    (write-cell sheet excel-row 6 length)

    (setq index (1+ index))
    (setq excel-row (1+ excel-row))
  )

  ;; Write the total
  (write-cell sheet excel-row 5 "TOTAL")
  (write-cell sheet excel-row 6 total-length)

  ;; Auto-fit column widths
  (vlax-invoke-method
    (vlax-get-property
      (vlax-get-property sheet 'UsedRange)
      'Columns)
    'AutoFit
  )

  (princ (strcat "\n" (itoa (sslength selection-set)) " line(s) exported to Excel."))
  (princ (strcat "\nTotal length: " (rtos total-length 2 2)))

  ;; Release COM objects
  (vlax-release-object sheet)
  (vlax-release-object workbook)
  (vlax-release-object workbooks)
  ;; Do not release excel so the user can review the result

  (princ)
)

Note: this example uses the write-cell function defined above. In practice, you would place it in a utility file loaded before your main program.

Releasing COM Objects

Every call to vlax-get-property or vlax-invoke-method that returns a COM object allocates memory. If you don't release these objects, the memory is never reclaimed — this is a memory leak.

The rule is simple: release COM objects in the reverse order of their creation:

;; Creation: excel → workbooks → workbook → sheet
;; Release: sheet → workbook → workbooks → excel

(vlax-release-object sheet)
(vlax-release-object workbook)
(vlax-release-object workbooks)
(vlax-release-object excel)

If you don't release the excel object, the Excel instance will remain in memory even after its window is closed (visible in Task Manager).

Best practice: in a production program, wrap your ActiveX code in an *error* handler (covered in chapter 11) to ensure COM objects are released even if the program is interrupted.

Accessing the AutoCAD Object Model

ActiveX interoperability isn't just for controlling external applications. AutoCAD itself exposes a COM object model that you can manipulate from AutoLISP. It's an alternative to the entmake/entmod functions:

;; Access the current document
(setq document (vla-get-ActiveDocument (vlax-get-acad-object)))

;; Access model space
(setq model-space (vla-get-ModelSpace document))

;; Create a circle via ActiveX
(setq center (vlax-3d-point 50.0 50.0 0.0))
(setq circle (vla-AddCircle model-space center 25.0))

;; Modify its properties
(vla-put-Color circle acRed)
(vla-put-Layer circle "Construction")

The vla-* functions are shortcuts automatically generated by Visual LISP for AutoCAD objects. They are equivalent to vlax-get-property / vlax-put-property / vlax-invoke-method but with a more concise syntax.

Summary

Concept Function Description
Launch an application vlax-get-or-create-object Connects to or launches the application
Existing application vlax-get-object Connects only if already running
Read a property vlax-get-property Retrieves the value of a COM property
Modify a property vlax-put-property Changes the value of a COM property
Call a method vlax-invoke-method Executes an action on a COM object
Release an object vlax-release-object Frees memory allocated for the object
AutoCAD object vlax-get-acad-object Accesses the AutoCAD application itself
3D point for ActiveX vlax-3d-point Creates a 3D point variant for vla-* methods

Tutorial Conclusion

Congratulations! You've covered all of AutoLISP, from your first (alert "Hello!") expression to interoperability with external applications. Here is a summary of your journey:

  1. Introduction — The origins of LISP and Autodesk's choice
  2. Getting Started — The command line and alert
  3. Syntax — Prefix notation and parentheses
  4. Mathematics — Arithmetic operations
  5. Variablessetq and data types
  6. Functionsdefun and c: commands
  7. Control Flowif, cond, while, and repeat
  8. Lists — The fundamental data structure
  9. Interacting with the Drawingcommand, entmake, and entmod
  10. Reading and Writing Filesopen, read-line, write-line, findfile
  11. Error Handling*error* and state restoration
  12. Symbols and Lambda — Functional programming
  13. Extended Data and Dictionaries — Xdata, xrecords, and handles
  14. Reactors — Monitoring and responding to events
  15. ActiveX Interoperability — Controlling Excel and the AutoCAD object model

You now have a solid foundation to start writing your own AutoLISP scripts. What's next? Open AutoCAD, identify a repetitive task in your daily work, and try to automate it. Practice is the best way to learn.


Helping hand Need an AutoCAD (AutoLISP, ObjectARX, .NET, VBA) development? Contact me for a free quote.