Importer des calques Excel dans un dessin AutoCAD

Bonjour, parmi les demandes d’automatisation AutoCAD il y a la très classique méthode pour importer des lignes Excel dans un dessin AutoCAD.

Voici une demande tirée du forum Autodesk AutoCAD à laquelle il peut être répondu de différentes façons. En particulier, vous pourriez utiliser une génération automatique de programme AutoLISP par IA, ça se fait en 5 minutes :wink:.

Vous trouverez dans le Zip le fichier Excel proposé par le demandeur, l’enregistrement en CSV, et le programme LISP. (testé dans AutoCAD LT2027)

ImportCalquesCSV.zip (7,0 Ko)

(vl-load-com)

(defun c:ImportCalquesCSV ( / fichier f ligne lst nom descr couleur typeligne epaisseur cmdEcho_sav)
  (setq cmdEcho_sav (getvar "CMDECHO"))
  (setvar "CMDECHO" 0)

  (setq fichier (getfiled "Sélectionnez le fichier CSV des calques" "" "csv" 4))
  
  (if fichier
    (progn
      (setq f (open fichier "r"))
      ;; Ignorer la première ligne (en-têtes)
      (read-line f)
      
      (while (setq ligne (read-line f))
        (setq lst (SplitString ligne ";"))
        
        (if (and (>= (length lst) 5) (not (eq (car lst) "")))
          (progn
            (setq nom       (nth 0 lst)
                  descr     (nth 1 lst)
                  couleur   (nth 2 lst)
                  typeligne (nth 3 lst)
                  epaisseur (nth 4 lst)
            )
            
            ;; Nettoyage des guillemets
            (while (vl-string-search "\"" descr)
              (setq descr (vl-string-subst "" "\"" descr))
            )
            
            ;; Remplacer virgule par point pour l'épaisseur
            (if (vl-string-search "," epaisseur)
              (setq epaisseur (vl-string-subst "." "," epaisseur))
            )

            ;; 1. Création du calque
            (vl-cmdf "_.-LAYER" "_Make" nom "")
            
            ;; 2. Application de la couleur
            (vl-cmdf "_.-LAYER" "_Color" couleur nom "")

            ;; 3. Gestion robuste du Type de Ligne
            (setq typeligne (vl-string-trim " " typeligne))
            (if (or (= (strcase typeligne) "CONTINU") (= (strcase typeligne) "CONTINUOUS"))
              (setq typeligne "Continuous")
              (progn
                ;; Tenter de charger le type de ligne s'il n'est pas dans le dessin
                (if (not (tblsearch "LTYPE" typeligne))
                  (vl-cmdf "_.-LINETYPE" "_Load" typeligne "acadiso.lin" "")
                )
                ;; Si toujours introuvable après tentative de chargement, forcer en Continuous
                (if (not (tblsearch "LTYPE" typeligne))
                  (progn
                    (princ (strcat "\n[Avertissement] Type de ligne '" typeligne "' introuvable pour le calque " nom ". Remplacé par Continuous."))
                    (setq typeligne "Continuous")
                  )
                )
              )
            )
            (vl-cmdf "_.-LAYER" "_Ltype" typeligne nom "")

            ;; 4. Application de l'épaisseur
            (vl-cmdf "_.-LAYER" "_LWeight" epaisseur nom "")

            ;; 5. Application de la description (seulement si la case n'est pas vide)
            (if (and descr (/= descr ""))
              (vl-cmdf "_.-LAYER" "_Description" descr nom "")
            )
          )
        )
      )
      (close f)
      (princ "\nImportation des calques terminée avec succès !")
    )
    (princ "\nOpération annulée : Aucun fichier sélectionné.")
  )
  
  (setvar "CMDECHO" cmdEcho_sav)
  (princ)
)

;;--- Fonction utilitaire pour découper une chaîne de caractères ---
(defun SplitString (str delim / pos lst)
  (while (setq pos (vl-string-search delim str))
    (setq lst (cons (substr str 1 pos) lst))
    (setq str (substr str (+ pos 1 (strlen delim))))
  )
  (reverse (cons str lst))
)

Résultat:

Vous pouvez bien entendu vous inspirer de ce programme pour importer d’autres types de symboles dans les tables de symboles AutoCAD.

Et voici pour les vraiment débutants AutoLISP la même version, mais commentée de façon très pédagogique. On a tous commencé un jour, n’est-ce pas ? :wink:

;;; ==============================================================================
;;; NOM DU SCRIPT : ImportCalquesCSV_Pedagogique.lsp
;;; DESCRIPTION   : Importe une liste de calques depuis un fichier CSV vers AutoCAD
;;; NIVEAU        : Débutant / Intermédiaire
;;; ==============================================================================

;; 1. INITIALISATION DES FONCTIONS AVANCÉES
;; La fonction (vl-load-com) charge les extensions Visual LISP. 
;; C'est indispensable pour utiliser les fonctions qui commencent par "vl-", "vla-" ou "vlax-".
;; On la place toujours au tout début d'un fichier LISP.
(vl-load-com)

;;; ==============================================================================
;;; FONCTION PRINCIPALE
;;; ==============================================================================

;; 2. DÉFINITION DE LA COMMANDE
;; (defun ...) signifie "Define Function" (Définir une fonction).
;; Le "c:" avant le nom signifie que cette fonction deviendra une commande AutoCAD 
;; tapable directement au clavier (ici : IMPORTCALQUESCSV).
;; 
;; Les éléments entre parenthèses ( / fichier f ...) sont les VARIABLES LOCALES.
;; Le slash "/" sépare les arguments (s'il y en a) des variables. 
;; Déclarer les variables ici permet de vider la mémoire de l'ordinateur une fois le script terminé.
(defun c:ImportCalquesCSV ( / fichier f ligne lst nom descr couleur typeligne epaisseur cmdEcho_sav)

  ;; 3. GESTION DE L'AFFICHAGE (Optionnel mais recommandé)
  ;; "CMDECHO" est une variable système d'AutoCAD qui contrôle si on voit le texte des commandes défiler en bas.
  ;; On sauvegarde sa valeur actuelle (souvent 1) dans notre variable "cmdEcho_sav" avec (getvar ...).
  (setq cmdEcho_sav (getvar "CMDECHO"))
  ;; Puis on la met à 0 avec (setvar ...) pour que le script travaille de façon "silencieuse" et propre.
  (setvar "CMDECHO" 0)

  ;; 4. BOÎTE DE DIALOGUE POUR CHOISIR LE FICHIER
  ;; (getfiled) ouvre la fenêtre Windows "Sélectionner un fichier".
  ;; Arguments : "Titre", "Dossier par défaut", "Extension", Mode (4 = chercher un fichier existant).
  ;; Le chemin du fichier choisi est stocké dans la variable "fichier".
  (setq fichier (getfiled "Sélectionnez le fichier CSV des calques" "" "csv" 4))
  
  ;; 5. VÉRIFICATION : L'UTILISATEUR A-T-IL CHOISI UN FICHIER ?
  ;; (if ...) est une condition. "Si 'fichier' contient quelque chose..."
  (if fichier
    ;; (progn ...) permet de regrouper plusieurs actions si la condition est VRAIE. 
    ;; Sans (progn), (if) ne peut exécuter qu'une seule action pour le VRAI et une pour le FAUX.
    (progn
      
      ;; 6. OUVERTURE DU FICHIER TEXTE
      ;; (open fichier "r") ouvre le fichier en mode "Read" (Lecture).
      (setq f (open fichier "r"))
      
      ;; (read-line f) lit la toute première ligne du fichier.
      ;; On l'appelle ici dans le vide pour "sauter" la ligne des en-têtes (Nom de calque, etc.).
      (read-line f)
      
      ;; 7. BOUCLE DE LECTURE LIGNE PAR LIGNE
      ;; (while ...) répète les actions tant que la condition est vraie.
      ;; Ici, on stocke la ligne lue dans la variable "ligne". Quand on arrive à la fin du fichier, 
      ;; (read-line) renvoie "nil" (vide), ce qui arrête la boucle.
      (while (setq ligne (read-line f))
        
        ;; On utilise notre sous-fonction personnalisée (tout en bas du code) pour découper
        ;; la ligne de texte en une liste de mots, en utilisant le point-virgule comme séparateur.
        ;; Exemple : "Mur;Rouge;Continu" devient la liste ("Mur" "Rouge" "Continu")
        (setq lst (SplitString ligne ";"))
        
        ;; 8. VÉRIFICATION DE LA LIGNE
        ;; (and ...) s'assure que TOUTES les conditions sont vraies.
        ;; On vérifie : 1. Qu'il y a bien au moins 5 colonnes (length lst)
        ;;              2. Que la première colonne n'est pas vide (not (eq (car lst) ""))
        (if (and (>= (length lst) 5) (not (eq (car lst) "")))
          (progn
            
            ;; 9. RÉPARTITION DES DONNÉES DANS DES VARIABLES
            ;; (nth X lst) récupère l'élément numéro X d'une liste. Attention, on commence à compter à Zéro !
            (setq nom       (nth 0 lst)
                  descr     (nth 1 lst)
                  couleur   (nth 2 lst)
                  typeligne (nth 3 lst)
                  epaisseur (nth 4 lst)
            )
            
            ;; 10. NETTOYAGE DES DONNÉES (Gestion des bugs d'Excel)
            ;; Excel rajoute parfois des guillemets (") inutiles autour des textes dans les CSV.
            ;; On cherche un guillemet avec (vl-string-search). S'il y en a un, on le remplace par du vide "".
            (while (vl-string-search "\"" descr)
              (setq descr (vl-string-subst "" "\"" descr))
            )
            
            ;; AutoCAD utilise le point (.) pour les décimales, mais Excel FR utilise la virgule (,).
            ;; On cherche la virgule dans l'épaisseur et on la remplace par un point (ex: 0,25 -> 0.25).
            (if (vl-string-search "," epaisseur)
              (setq epaisseur (vl-string-subst "." "," epaisseur))
            )

            ;; 11. ENVOI DES COMMANDES À AUTOCAD
            ;; On utilise (vl-cmdf) au lieu de (command) car c'est plus sécurisé : 
            ;; il vérifie que les données sont valides avant de les lancer.
            
            ;; Création du calque (_Make)
            (vl-cmdf "_.-LAYER" "_Make" nom "")
            
            ;; Application de la couleur (_Color)
            (vl-cmdf "_.-LAYER" "_Color" couleur nom "")

            ;; 12. GESTION COMPLEXE : LE TYPE DE LIGNE
            ;; (vl-string-trim) enlève les espaces vides au début ou à la fin du mot.
            (setq typeligne (vl-string-trim " " typeligne))
            
            ;; Si le mot est "Continu" ou "Continuous"...
            (if (or (= (strcase typeligne) "CONTINU") (= (strcase typeligne) "CONTINUOUS"))
              ;; ...On force l'anglais "Continuous" qu'AutoCAD comprend toujours.
              (setq typeligne "Continuous")
              
              ;; Sinon (c'est un autre type comme Divise ou Fantome)...
              (progn
                ;; (tblsearch) cherche dans la base de données du dessin.
                ;; On regarde si le type de ligne existe déjà. Si (not ...) (s'il n'existe pas) :
                (if (not (tblsearch "LTYPE" typeligne))
                  ;; On demande à AutoCAD de le charger depuis son fichier système "acadiso.lin".
                  (vl-cmdf "_.-LINETYPE" "_Load" typeligne "acadiso.lin" "")
                )
                
                ;; Si, après ça, il n'existe TOUJOURS PAS (faute de frappe dans le CSV par exemple) :
                (if (not (tblsearch "LTYPE" typeligne))
                  (progn
                    ;; On affiche un message d'avertissement à l'utilisateur (princ = print character)
                    (princ (strcat "\n[Avertissement] Type de ligne '" typeligne "' introuvable. Remplacé par Continuous."))
                    ;; On le remplace par Continues pour ne pas faire planter la suite du script.
                    (setq typeligne "Continuous")
                  )
                )
              )
            )
            ;; Enfin, on applique le type de ligne validé au calque (_Ltype)
            (vl-cmdf "_.-LAYER" "_Ltype" typeligne nom "")

            ;; Application de l'épaisseur de ligne (_LWeight)
            (vl-cmdf "_.-LAYER" "_LWeight" epaisseur nom "")

            ;; 13. LA DESCRIPTION
            ;; On applique la description uniquement s'il y a du texte à appliquer (non vide)
            (if (and descr (/= descr ""))
              (vl-cmdf "_.-LAYER" "_Description" descr nom "")
            )
            
          ) ;; Fin du (progn) de la ligne en cours
        ) ;; Fin du (if) de la ligne en cours
      ) ;; Fin de la boucle (while)
      
      ;; 14. NETTOYAGE DE FIN
      ;; On ferme proprement le fichier texte ouvert en mémoire. C'est très important !
      (close f)
      ;; On indique à l'utilisateur que tout s'est bien passé.
      (princ "\nImportation des calques terminée avec succès !")
      
    ) ;; Fin du (progn) de condition fichier "VRAI"
    
    ;; 15. CAS OÙ L'UTILISATEUR N'A PAS CHOISI DE FICHIER (Condition fichier "FAUX")
    (princ "\nOpération annulée : Aucun fichier sélectionné.")
  ) ;; Fin du (if)
  
  ;; 16. RESTAURATION DU SYSTÈME
  ;; On remet l'affichage des commandes tel qu'il était avant de lancer le script.
  (setvar "CMDECHO" cmdEcho_sav)
  
  ;; (princ) vide à la fin empêche AutoLISP d'afficher la dernière valeur lue dans la console, 
  ;; ce qui permet une sortie de commande propre.
  (princ)
)

;;; ==============================================================================
;;; SOUS-FONCTIONS UTILITAIRES
;;; ==============================================================================

;; Fonction qui découpe une phrase (str) à chaque fois qu'elle rencontre un caractère précis (delim)
;; Elle renvoie une liste. C'est le fonctionnement classique d'un "Split" en programmation.
(defun SplitString (str delim / pos lst)
  ;; Tant qu'on trouve le séparateur dans le texte...
  (while (setq pos (vl-string-search delim str))
    ;; On coupe le morceau avant le séparateur et on l'ajoute à notre liste (cons)
    (setq lst (cons (substr str 1 pos) lst))
    ;; On raccourcit le texte d'origine pour chercher le prochain séparateur
    (setq str (substr str (+ pos 1 (strlen delim))))
  )
  ;; On ajoute le tout dernier morceau restant, et on inverse la liste (reverse)
  ;; car la fonction (cons) ajoute les éléments au début de la liste, à l'envers.
  (reverse (cons str lst))
)