Interopérabilité ActiveX
AutoLISP, via les extensions Visual LISP, peut communiquer avec n'importe quelle application supportant ActiveX/COM (Component Object Model). L'exemple le plus courant est l'interaction avec Microsoft Excel pour exporter des données ou générer des rapports, mais le même principe s'applique à Word, Outlook, ou toute autre application exposant une interface COM.
Important : la communication ActiveX ne fonctionne que sous Windows. Les versions d'AutoCAD pour Mac ne supportent pas Visual LISP ActiveX.
Le modèle COM en bref
Le modèle COM repose sur trois concepts :
- Objets : des entités logicielles qui exposent des fonctionnalités (un classeur Excel, une feuille de calcul, une cellule)
- Propriétés : des valeurs qu'on peut lire ou modifier sur un objet (la valeur d'une cellule, la visibilité de l'application)
- Méthodes : des actions qu'on peut exécuter sur un objet (ajouter un classeur, enregistrer un fichier)
Depuis AutoLISP, on manipule ces objets avec les fonctions vlax-*.
Les fonctions clés
| Fonction | Rôle |
|---|---|
vlax-get-or-create-object |
Se connecter à une application (la lance si nécessaire) |
vlax-get-object |
Se connecter à une application déjà en cours d'exécution |
vlax-get-property |
Lire une propriété d'un objet COM |
vlax-put-property |
Modifier une propriété d'un objet COM |
vlax-invoke-method |
Appeler une méthode d'un objet COM |
vlax-release-object |
Libérer un objet COM (évite les fuites mémoire) |
Se connecter à une application
;; Lancer Excel (ou se connecter à une instance existante)
(setq excel (vlax-get-or-create-object "Excel.Application"))
;; Se connecter uniquement si Excel est déjà ouvert (retourne nil sinon)
(setq excel (vlax-get-object "Excel.Application"))
Les noms d'application COM courants :
| Application | Identifiant COM |
|---|---|
| Microsoft Excel | "Excel.Application" |
| Microsoft Word | "Word.Application" |
| Microsoft Outlook | "Outlook.Application" |
Naviguer dans la hiérarchie d'objets
Les applications COM exposent une hiérarchie d'objets. Pour Excel, la chaîne est : Application → Workbooks → Workbook → Worksheets → Worksheet → Cells → Cell. On navigue d'un niveau à l'autre avec vlax-get-property :
(setq classeurs (vlax-get-property excel 'Workbooks))
(setq classeur (vlax-invoke-method classeurs 'Add))
(setq feuille (vlax-get-property classeur 'ActiveSheet))
Simplifier les accès aux cellules
Le code pour écrire dans une cellule Excel est assez verbeux avec les fonctions vlax-* brutes. On peut le factoriser dans des fonctions utilitaires :
(defun ecrire-cellule (feuille ligne colonne valeur / cellule)
(setq cellule
(vlax-get-property
(vlax-get-property feuille 'Cells)
'Item ligne colonne
)
)
(vlax-put-property cellule 'Value valeur)
)
(defun lire-cellule (feuille ligne colonne / cellule)
(setq cellule
(vlax-get-property
(vlax-get-property feuille 'Cells)
'Item ligne colonne
)
)
(vlax-get-property cellule 'Value)
)
Utilisation :
(ecrire-cellule feuille 1 1 "N°")
(ecrire-cellule feuille 1 2 "Longueur")
(ecrire-cellule feuille 2 1 1)
(ecrire-cellule feuille 2 2 42.5)
(lire-cellule feuille 2 2) ; → 42.5
Exemple complet : exporter un métré vers Excel
Ce programme sélectionne toutes les lignes du dessin, calcule leur longueur totale et exporte le détail dans une feuille Excel :
(defun c:metre-excel (/ jeu index entite donnees point-depart point-arrivee
longueur excel classeurs classeur feuille
ligne-excel longueur-totale)
;; Sélectionner toutes les lignes
(setq jeu (ssget "_X" '((0 . "LINE"))))
(if (null jeu)
(progn (princ "\nAucune ligne trouvée.") (princ) (exit))
)
;; Lancer Excel (ou se connecter à une instance existante)
(setq excel (vlax-get-or-create-object "Excel.Application"))
;; Rendre Excel visible
(vlax-put-property excel 'Visible :vlax-true)
;; Créer un nouveau classeur
(setq classeurs (vlax-get-property excel 'Workbooks))
(setq classeur (vlax-invoke-method classeurs 'Add))
(setq feuille (vlax-get-property classeur 'ActiveSheet))
;; Écrire les en-têtes
(ecrire-cellule feuille 1 1 "N°")
(ecrire-cellule feuille 1 2 "X1")
(ecrire-cellule feuille 1 3 "Y1")
(ecrire-cellule feuille 1 4 "X2")
(ecrire-cellule feuille 1 5 "Y2")
(ecrire-cellule feuille 1 6 "Longueur")
;; Parcourir les lignes du dessin
(setq index 0)
(setq ligne-excel 2)
(setq longueur-totale 0.0)
(repeat (sslength jeu)
(setq entite (ssname jeu index))
(setq donnees (entget entite))
(setq point-depart (cdr (assoc 10 donnees)))
(setq point-arrivee (cdr (assoc 11 donnees)))
;; Calculer la longueur
(setq longueur (distance point-depart point-arrivee))
(setq longueur-totale (+ longueur-totale longueur))
;; Écrire dans Excel
(ecrire-cellule feuille ligne-excel 1 (1+ index))
(ecrire-cellule feuille ligne-excel 2 (nth 0 point-depart))
(ecrire-cellule feuille ligne-excel 3 (nth 1 point-depart))
(ecrire-cellule feuille ligne-excel 4 (nth 0 point-arrivee))
(ecrire-cellule feuille ligne-excel 5 (nth 1 point-arrivee))
(ecrire-cellule feuille ligne-excel 6 longueur)
(setq index (1+ index))
(setq ligne-excel (1+ ligne-excel))
)
;; Écrire le total
(ecrire-cellule feuille ligne-excel 5 "TOTAL")
(ecrire-cellule feuille ligne-excel 6 longueur-totale)
;; Ajuster la largeur des colonnes
(vlax-invoke-method
(vlax-get-property
(vlax-get-property feuille 'UsedRange)
'Columns)
'AutoFit
)
(princ (strcat "\n" (itoa (sslength jeu)) " ligne(s) exportée(s) vers Excel."))
(princ (strcat "\nLongueur totale : " (rtos longueur-totale 2 2)))
;; Libérer les objets COM
(vlax-release-object feuille)
(vlax-release-object classeur)
(vlax-release-object classeurs)
;; Ne pas libérer excel pour laisser l'utilisateur consulter le résultat
(princ)
)
Remarque : cet exemple utilise la fonction
ecrire-celluledéfinie plus haut. En pratique, vous la placeriez dans un fichier utilitaire chargé avant votre programme principal.
Libérer les objets COM
Chaque appel à vlax-get-property ou vlax-invoke-method qui retourne un objet COM alloue de la mémoire. Si vous ne libérez pas ces objets, la mémoire n'est jamais récupérée — c'est une fuite mémoire.
La règle est simple : libérez les objets COM dans l'ordre inverse de leur création :
;; Création : excel → classeurs → classeur → feuille
;; Libération : feuille → classeur → classeurs → excel
(vlax-release-object feuille)
(vlax-release-object classeur)
(vlax-release-object classeurs)
(vlax-release-object excel)
Si vous ne libérez pas l'objet excel, l'instance d'Excel restera en mémoire même après la fermeture de sa fenêtre (visible dans le Gestionnaire des tâches).
Bonne pratique : dans un programme de production, encadrez votre code ActiveX dans un gestionnaire d'erreur
*error*(vu au chapitre 11) pour garantir la libération des objets COM même en cas d'interruption.
Accéder au modèle objet d'AutoCAD
L'interopérabilité ActiveX ne sert pas qu'à piloter des applications externes. AutoCAD lui-même expose un modèle objet COM que vous pouvez manipuler depuis AutoLISP. C'est une alternative aux fonctions entmake/entmod :
;; Accéder au document courant
(setq document (vla-get-ActiveDocument (vlax-get-acad-object)))
;; Accéder à l'espace modèle
(setq espace-modele (vla-get-ModelSpace document))
;; Créer un cercle via ActiveX
(setq centre (vlax-3d-point 50.0 50.0 0.0))
(setq cercle (vla-AddCircle espace-modele centre 25.0))
;; Modifier ses propriétés
(vla-put-Color cercle acRed)
(vla-put-Layer cercle "Construction")
Les fonctions vla-* sont des raccourcis générés automatiquement par Visual LISP pour les objets AutoCAD. Elles sont équivalentes à vlax-get-property / vlax-put-property / vlax-invoke-method mais avec une syntaxe plus concise.
Résumé
| Concept | Fonction | Description |
|---|---|---|
| Lancer une application | vlax-get-or-create-object |
Se connecte ou lance l'application |
| Application existante | vlax-get-object |
Se connecte uniquement si déjà lancée |
| Lire une propriété | vlax-get-property |
Récupère la valeur d'une propriété COM |
| Modifier une propriété | vlax-put-property |
Change la valeur d'une propriété COM |
| Appeler une méthode | vlax-invoke-method |
Exécute une action sur un objet COM |
| Libérer un objet | vlax-release-object |
Libère la mémoire allouée pour l'objet |
| Objet AutoCAD | vlax-get-acad-object |
Accède à l'application AutoCAD elle-même |
| Point 3D pour ActiveX | vlax-3d-point |
Crée un variant point 3D pour les méthodes vla-* |
Conclusion du tutoriel
Félicitations ! Vous avez parcouru l'ensemble d'AutoLISP, depuis votre première expression (alert "Bonjour !") jusqu'à l'interopérabilité avec des applications externes. Voici un résumé de votre parcours :
- Introduction — Les origines de LISP et le choix d'Autodesk
- Premiers pas — La ligne de commande et
alert - Syntaxe — La notation préfixée et les parenthèses
- Mathématiques — Les opérations de calcul
- Variables —
setqet les types de données - Fonctions —
defunet les commandesc: - Contrôle —
if,cond,whileetrepeat - Listes — La structure de données fondamentale
- Interagir avec le dessin —
command,entmakeetentmod - Lire et écrire des fichiers —
open,read-line,write-line,findfile - Gestion des erreurs —
*error*et la restauration d'état - Symboles et lambda — La programmation fonctionnelle
- Données étendues et dictionnaires — Xdata, xrecords et handles
- Les reactors — Surveiller et réagir aux événements
- Interopérabilité ActiveX — Piloter Excel et le modèle objet d'AutoCAD
Vous avez maintenant les bases solides pour commencer à écrire vos propres scripts AutoLISP. La prochaine étape ? Ouvrez AutoCAD, identifiez une tâche répétitive dans votre travail quotidien, et essayez de l'automatiser. C'est en pratiquant qu'on apprend le mieux.
Besoin d'un développement AutoCAD (AutoLISP, ObjectARX, .NET, VBA) ? Contactez-moi pour un devis gratuit.