AutoLISP : Incrémenter un ID dans les Données d'Objet (OD)

Comment créer un script AutoLISP pour incrémenter automatiquement un identifiant (ID) dans un champ de Données d’Objet (OD) attaché à des objets AutoCAD ? La routine doit permettre de définir une valeur de départ (numérique ou alphanumérique) et de l’appliquer à une sélection multiple d’objets.

Pour incrémenter automatiquement un identifiant dans un champ de Données d’Objet (OD), il est nécessaire d’utiliser des fonctions AutoLISP spécifiques à l’environnement AutoCAD Map 3D ou Civil 3D, notamment ade_odsetfield. La solution consiste à créer une routine LISP qui gère la sélection d’objets, une valeur de départ et son incrémentation pour chaque objet.

Voici une procédure complète et un code fonctionnel pour réaliser cette tâche.

Étape 1 : Préparation du code AutoLISP

Le script se compose de deux fonctions : inc_txt pour gérer l’incrémentation alphanumérique complexe, et c:numeroter qui est la commande principale.

Copiez le code suivant dans un fichier texte et enregistrez-le avec une extension .lsp (par exemple, Increment-OD.lsp).

;; Fonction pour incrémenter une chaîne alphanumérique (ex: A9 -> B0, Z -> AA)
(defun inc_txt (Txt / Boucle Decalage Val_Txt Ascii_Txt)
  (setq Boucle 1 Val_txt "")
  (while (<= Boucle (strlen Txt))
    (setq Ascii_Txt (vl-string-elt Txt (- (strlen Txt) Boucle)))
    (if (not Decalage)
      (setq Ascii_Txt (1+ Ascii_Txt))
    )
    (if (or (= Ascii_Txt 58) (= Ascii_Txt 91) (= Ascii_Txt 123))
      (setq
        Ascii_Txt
        (cond
          ((= Ascii_Txt 58) 48) ; Dépassement de '9', retour à '0'
          ((= Ascii_Txt 91) 65) ; Dépassement de 'Z', retour à 'A'
          ((= Ascii_Txt 123) 97) ; Dépassement de 'z', retour à 'a'
        )
        Decalage nil
      )
      (setq Decalage T)
    )
    (setq Val_Txt (strcat (chr Ascii_Txt) Val_Txt))
    (setq Boucle (1+ Boucle))
  )
  (if (not Decalage)
    (setq Val_Txt (strcat (cond ((< Ascii_Txt 58) "0") ((< Ascii_Txt 91) "A") ((< Ascii_Txt 123) "a")) Val_Txt))
  )
  Val_Txt
)

;; Commande principale pour numéroter les objets
(defun c:numeroter ( / sv_zp n_ini js n ename nb nb_dec inc n_next)
  ;; Pour réinitialiser le compteur entre deux utilisations, tapez (setq n_next nil) en ligne de commande

  ;; --- SECTION À PERSONNALISER ---
  (setq nom_table "RACCORD")    ; <--- MODIFIEZ ICI le nom de votre table OD
  (setq nom_champ "IDRACCORD")  ; <--- MODIFIEZ ICI le nom de votre champ OD
  ;; --------------------------------

  (setq sv_zp (getvar "dimzin"))
  (setvar "dimzin" 4)

  (if (not n_next)
    (setq n_ini (getstring "\nIncrémenter en débutant à [chiffre/lettre/alphanumérique]: "))
    (setq n_ini n_next)
  )

  (prompt "\nSélectionnez les objets à numéroter...")
  (setq js (ssget))

  (if js
    (progn
      (repeat (setq n (sslength js))
        (setq ename (ssname js (setq n (1- n))))
        (cond
          ;; Cas d'une valeur de départ entière
          ((eq (type (read n_ini)) 'INT)
            (setq n_next (itoa (1+ (atoi n_ini))))
            ; On écrit la valeur en tant que chaîne de caractères, compatible avec les champs Texte
            (ade_odsetfield ename nom_table nom_champ 0 n_next)
          )
          ;; Cas d'une valeur de départ réelle (décimale)
          ((eq (type (read n_ini)) 'REAL)
            (setq nb 0)
            (repeat (strlen n_ini)
              (if (eq (substr n_ini (setq nb (1+ nb)) 1) ".")
                (setq nb_dec (1- (strlen (substr n_ini nb))))
              )
            )
            (setq inc 1.0)
            (repeat nb_dec (setq inc (/ inc 10)))
            (setq n_next (rtos (+ inc (atof n_ini)) 2 nb_dec))
            (ade_odsetfield ename nom_table nom_champ 0 n_next)
          )
          ;; Cas d'une valeur de départ alphanumérique
          ((eq (type n_ini) 'STR)
            (setq n_next (inc_txt n_ini))
            (ade_odsetfield ename nom_table nom_champ 0 n_next)
          )
        )
        (setq n_ini n_next) ; Mise à jour de la valeur pour la prochaine itération
      )
    )
  )
  (setvar "dimzin" sv_zp)
  (print (strcat "\nDernière valeur utilisée : " n_next))
  (prin1)
)

Étape 2 : Personnalisation du Script

Avant d’utiliser le script, vous devez l’adapter à votre projet :

  1. Ouvrez le fichier .lsp.
  2. Localisez la section --- SECTION À PERSONNALISER ---.
  3. Remplacez "RACCORD" par le nom exact de votre table de Données d’Objet.
  4. Remplacez "IDRACCORD" par le nom exact du champ que vous souhaitez renseigner.

Étape 3 : Chargement et Utilisation

  1. Charger le script : Dans AutoCAD, tapez la commande APPLOAD, sélectionnez votre fichier Increment-OD.lsp et cliquez sur « Charger ».
  2. Lancer la commande : Tapez NUMEROTER dans la ligne de commande et validez.
  3. Valeur de départ : Le programme vous demande une valeur de départ. Entrez une valeur (ex: 1000, A1, P-001).
  4. Sélection : Sélectionnez les objets que vous souhaitez numéroter. Vous pouvez utiliser tous les modes de sélection (fenêtre, capture, etc.).
  5. Résultat : Le script parcourt chaque objet sélectionné et remplit le champ OD spécifié avec la valeur incrémentée.

Points d’attention et Bonnes Pratiques

  • Prérequis Logiciel : Les fonctions ade_* (ade_odsetfield, etc.) sont spécifiques à AutoCAD Map 3D et AutoCAD Civil 3D. Ce script ne fonctionnera pas sur une version standard d’AutoCAD (« vanilla »).
  • Type de champ OD : Le code a été adapté pour écrire la valeur numérique sous forme de texte ((itoa ...)), ce qui le rend compatible avec les champs OD de type « Caractère » (String). C’est une pratique plus sûre car un champ texte peut stocker des chiffres, mais l’inverse n’est pas vrai.
  • Ordre de numérotation : La commande ssget ne garantit pas un ordre de sélection prévisible (spatial ou chronologique). La numérotation suivra l’ordre interne du jeu de sélection, qui est souvent l’ordre inverse de création des objets. Pour un contrôle total de l’ordre, il est préférable de sélectionner les objets un par un.
  • Réinitialisation du compteur : La dernière valeur est mémorisée pour la prochaine utilisation de la commande. Pour démarrer une nouvelle séquence de numérotation, tapez (setq n_next nil) dans la ligne de commande avant de relancer NUMEROTER.