Mettre à jour un bloc dynamique AutoCAD avec des données Excel

J’ai créé un bloc dynamique AutoCAD représentant un cercle dont le diamètre doit varier selon des calculs Excel. Est-il possible d’importer directement ces valeurs Excel dans les propriétés de ma table de consultation de bloc dynamique ?

Les tables de consultation des blocs dynamiques AutoCAD ne permettent pas une importation directe de données Excel. Cependant, une automatisation est réalisable via un script personnalisé pour lier ces informations.

Voici la démarche recommandée pour automatiser la mise à jour :

  1. Préparer les données Excel : Calculez vos diamètres et exportez-les dans un format texte structuré, tel qu’un fichier CSV (Comma Separated Values).
  2. Développer un script personnalisé : Créez une routine en AutoLISP ou VBA (ou un autre langage de script externe) capable de lire ce fichier CSV.
  3. Mettre à jour les blocs : Le script devra ensuite parcourir les blocs concernés dans votre dessin AutoCAD et modifier leurs propriétés dynamiques (par exemple, le paramètre de diamètre) en utilisant les valeurs lues depuis le fichier CSV.

Il est important de noter que la commande native AutoCAD ‹ Lier à un fichier de données › (Data Link) permet uniquement d’afficher et de mettre à jour des tableaux dans le dessin, et non de piloter dynamiquement les propriétés des blocs.

Code LISP complet et fonctionnel :

;; Fonction pour lire un fichier CSV et mettre à jour les blocs dynamiques
;; Format CSV attendu : ID_BLOC,DIAMETRE
;; Exemple : CERCLE01,25.5

(defun C:UPDATEBLOCKS (/ csvfile file line data blockid diameter ss ent obj proplist i prop)
  (princ "\nMise à jour des blocs dynamiques depuis Excel/CSV")
  
  ;; Sélection du fichier CSV
  (setq csvfile (getfiled "Sélectionner le fichier CSV" "" "csv" 0))
  
  (if csvfile
    (progn
      ;; Ouverture du fichier CSV
      (setq file (open csvfile "r"))
      
      (if file
        (progn
          (princ (strcat "\nLecture du fichier : " csvfile))
          
          ;; Lecture ligne par ligne
          (while (setq line (read-line file))
            ;; Ignorer les lignes vides ou d'en-tête
            (if (and line (> (strlen line) 0) (not (wcmatch line "*ID_BLOC*")))
              (progn
                ;; Séparation des données (ID,DIAMETRE)
                (setq data (PARSE-CSV line))
                (setq blockid (nth 0 data))
                (setq diameter (atof (nth 1 data)))
                
                (if (and blockid (> diameter 0))
                  (progn
                    (princ (strcat "\nTraitement du bloc : " blockid " - Diamètre : " (rtos diameter)))
                    
                    ;; Recherche et mise à jour des blocs correspondants
                    (UPDATE-DYNAMIC-BLOCK blockid diameter)
                  )
                )
              )
            )
          )
          (close file)
          (princ "\nMise à jour terminée !")
        )
        (princ "\nErreur : Impossible d'ouvrir le fichier CSV")
      )
    )
    (princ "\nOpération annulée")
  )
  (princ)
)

;; Fonction pour parser une ligne CSV
(defun PARSE-CSV (line / result pos temp)
  (setq result '())
  (setq temp line)
  
  (while (setq pos (vl-string-search "," temp))
    (setq result (append result (list (substr temp 1 pos))))
    (setq temp (substr temp (+ pos 2)))
  )
  ;; Ajouter le dernier élément
  (setq result (append result (list temp)))
  result
)

;; Fonction pour mettre à jour un bloc dynamique spécifique
(defun UPDATE-DYNAMIC-BLOCK (blockname newdiameter / ss i ent obj proplist j prop)
  ;; Sélection de tous les blocs avec le nom spécifié
  (setq ss (ssget "X" (list (cons 0 "INSERT") (cons 2 blockname))))
  
  (if ss
    (progn
      (setq i 0)
      (repeat (sslength ss)
        (setq ent (ssname ss i))
        (setq obj (vlax-ename->vla-object ent))
        
        ;; Vérifier si c'est un bloc dynamique
        (if (= (vla-get-IsDynamicBlock obj) :vlax-true)
          (progn
            ;; Obtenir les propriétés dynamiques
            (setq proplist (vlax-invoke obj 'GetDynamicBlockProperties))
            
            ;; Parcourir les propriétés pour trouver celle du diamètre
            (setq j 0)
            (repeat (vlax-safearray-get-u-bound proplist 1)
              (setq prop (vlax-safearray-get-element proplist j))
              
              ;; Rechercher la propriété "Diametre" ou "Diameter" ou similaire
              (if (or (wcmatch (vla-get-PropertyName prop) "*DIAMETRE*")
                     (wcmatch (vla-get-PropertyName prop) "*DIAMETER*")
                     (wcmatch (vla-get-PropertyName prop) "*DIAM*"))
                (progn
                  ;; Mettre à jour la valeur
                  (vla-put-Value prop newdiameter)
                  (princ (strcat "\n  Bloc mis à jour : " blockname " - Nouveau diamètre : " (rtos newdiameter)))
                )
              )
              (setq j (1+ j))
            )
          )
          (princ (strcat "\n  Attention : " blockname " n'est pas un bloc dynamique"))
        )
        (setq i (1+ i))
      )
    )
    (princ (strcat "\n  Aucun bloc trouvé avec le nom : " blockname))
  )
)

;; Fonction alternative pour mettre à jour par Handle (plus précis)
(defun C:UPDATEBLOCKSBYHANDLE (/ csvfile file line data handle diameter ent obj proplist i prop)
  (princ "\nMise à jour des blocs dynamiques par Handle")
  
  ;; Format CSV attendu : HANDLE,DIAMETRE
  (setq csvfile (getfiled "Sélectionner le fichier CSV (Handle,Diametre)" "" "csv" 0))
  
  (if csvfile
    (progn
      (setq file (open csvfile "r"))
      
      (if file
        (progn
          (while (setq line (read-line file))
            (if (and line (> (strlen line) 0) (not (wcmatch line "*HANDLE*")))
              (progn
                (setq data (PARSE-CSV line))
                (setq handle (nth 0 data))
                (setq diameter (atof (nth 1 data)))
                
                (if (and handle (> diameter 0))
                  (progn
                    ;; Récupération de l'entité par son handle
                    (setq ent (handent handle))
                    
                    (if ent
                      (progn
                        (setq obj (vlax-ename->vla-object ent))
                        
                        (if (= (vla-get-IsDynamicBlock obj) :vlax-true)
                          (progn
                            (setq proplist (vlax-invoke obj 'GetDynamicBlockProperties))
                            
                            (setq i 0)
                            (repeat (vlax-safearray-get-u-bound proplist 1)
                              (setq prop (vlax-safearray-get-element proplist i))
                              
                              (if (or (wcmatch (vla-get-PropertyName prop) "*DIAMETRE*")
                                     (wcmatch (vla-get-PropertyName prop) "*DIAMETER*")
                                     (wcmatch (vla-get-PropertyName prop) "*DIAM*"))
                                (vla-put-Value prop diameter)
                              )
                              (setq i (1+ i))
                            )
                            (princ (strcat "\nBloc " handle " mis à jour avec diamètre : " (rtos diameter)))
                          )
                        )
                      )
                      (princ (strcat "\nErreur : Handle " handle " introuvable"))
                    )
                  )
                )
              )
            )
          )
          (close file)
        )
      )
    )
  )
  (princ)
)

;; Fonction utilitaire pour lister les propriétés d'un bloc sélectionné
(defun C:LISTBLOCKPROPS (/ ent obj proplist i prop)
  (princ "\nSélectionner un bloc dynamique pour lister ses propriétés :")
  (setq ent (car (entsel)))
  
  (if ent
    (progn
      (setq obj (vlax-ename->vla-object ent))
      
      (if (= (vla-get-IsDynamicBlock obj) :vlax-true)
        (progn
          (princ "\nPropriétés dynamiques du bloc :")
          (setq proplist (vlax-invoke obj 'GetDynamicBlockProperties))
          
          (setq i 0)
          (repeat (vlax-safearray-get-u-bound proplist 1)
            (setq prop (vlax-safearray-get-element proplist i))
            (princ (strcat "\n  " (itoa i) ". " (vla-get-PropertyName prop) 
                          " = " (vl-princ-to-string (vla-get-Value prop))))
            (setq i (1+ i))
          )
        )
        (princ "\nCe n'est pas un bloc dynamique")
      )
    )
  )
  (princ)
)

Instructions d’utilisation :

  1. Préparer le fichier CSV : Exportez vos données Excel au format CSV avec les colonnes :

    • Colonne 1 : Nom du bloc (ex: « CERCLE01 »)
    • Colonne 2 : Valeur du diamètre (ex: « 25.5 »)
  2. Charger le script : Copiez le code dans un fichier .lsp et chargez-le avec APPLOAD

  3. Exécuter : Tapez UPDATEBLOCKS dans AutoCAD et sélectionnez votre fichier CSV

  4. Alternative précise : Utilisez UPDATEBLOCKSBYHANDLE si vous connaissez les handles des blocs

  5. Diagnostic : Utilisez LISTBLOCKPROPS pour identifier les noms exacts des propriétés de vos blocs

Note importante : Adaptez les noms de propriétés dans le code selon votre bloc dynamique (« DIAMETRE », « DIAMETER », « RAYON », etc.)