Aller au contenu

Incrément ID des données d'objets (OD)


Cadiste

Messages recommandés

Bonjour,

 

Je reviens vers vous car je souhaiterai avoir votre avis d'expert ..

 

J'aurais besoin d'incrémenter automatiquement des ID d'objets (bloc, polyligne), à partir d'une valeur de départ définie par l'utilisateur...

 

Vous allez me répondre .... l'appli Incrément de Gile ...

 

En effet, cette appli est juste superbe ;-) (Merci Gile ..) .... seulement pour les blocs , l'appli renseigne des attributs et non un champ OD.. et c'est là que je suis bloqué...

 

Comment puis je faire, je n'ai pas trouvé de ligne de commande pour le faire en direct sinon...

Lien vers le commentaire
Partager sur d’autres sites

Salut,

si tu as la source du lisp de Gile, tu peux changer la partie qui écrit dans un attribut par :

(ecritodata entname "TABLE" "CHAMP" "mavaleurchaine")

 

;;usage (ecritodata (car (entsel "\nentité ?")) "TABLE" "CHAMP" "mavaleurchaine")
(defun ecritodata (ent table champ val / id res lt len rg i boucle )
 (if (setq lt (ade_odgettables ent))
      (if (member table lt)
 (progn
             (setq len (ade_odrecordqty ent table)) 
             (setq boucle 't)
             (setq i 0)
             (while (and (< i len) boucle)
               (if(setq id (ade_odgetrecord ent table i))
                 (progn
                   (setq res (ade_odgetrecfield id champ))
                   (if res
                     (progn
                       (setq rg i)
                       (setq boucle nil)
                     )
                   )
                 )
               )
               (setq i (+ 1 i))
             )               
             (if rg
               (ade_odsetfield ent table champ rg val)
	(prompt (strcat "\nLa table " table " ne contient pas de champ " champ) )   
        )
   )
        (progn
   (prompt (strcat "\nL'entité n'est pas reliée à la table " table))
          (command)
        )
      )
    )
 (princ)
)

Bon courage,

Gégé

----------------------------------------------------------------------

Site: https://www.g-eaux.fr

Blog: http://g-eaux.over-blog.com

Lien vers le commentaire
Partager sur d’autres sites

Bonjour Gégématic,

 

J'obtiens une erreur de syntaxe quand je remplace ecritodata (ent table champ val par ecritodata entname "RACCORD" "IDRACCORD" 2000..

 

Dans le cas présent, je souhaite remplir le champ IDRACCORD de la table RACCORD à partir de l'identifiant 2000..

Lien vers le commentaire
Partager sur d’autres sites

Bonjour Gégématic,

 

J'obtiens une erreur de syntaxe quand je remplace ecritodata (ent table champ val par ecritodata entname "RACCORD" "IDRACCORD" 2000..

 

Dans le cas présent, je souhaite remplir le champ IDRACCORD de la table RACCORD à partir de l'identifiant 2000..

 

Je crois que tu as mal compris les explications de Gégématic... pour faire les changements, ce n'est pas la fonction proposée qu'il faut changer, mais le lisp de (gile).

 

Autrement de façon sommaire, tu peux essayer ceci:

 

(defun inc_txt (Txt / Boucle Decalage Val_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)
					((= Ascii_Txt 91) 65)
					((= Ascii_Txt 123) 97)
				)
			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
)
(defun c:numeroter ( / sv_zp n_ini nb nb_dec inc)
;;
;;Tapez (setq n_next nil) à la ligne de commande
;;pour faire une autre incrementation
;;
(setq sv_zp (getvar "dimzin"))
(setvar "dimzin" 4)
(if (not n_next)
	(setq n_ini (getstring "\nIncrementer en débutant à [chiffre/lettre/alphanumérique]: "))
	(setq n_ini n_next)
)
(cond
	((eq (type (read n_ini)) 'INT)
		(setq n_next (itoa (1+ (atoi n_ini))))
		(ade_odsetfield (car (entsel)) "RACCORD" "IDRACCORD" 0 (atoi n_next))
	)
	((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 (car (entsel)) "RACCORD" "IDRACCORD" 0 (atof n_next))
	)
	((eq (type n_ini) 'STR)
		(setq n_next (inc_txt n_ini))
		(ade_odsetfield (car (entsel)) "RACCORD" "IDRACCORD" 0 n_next)
	)
)
(setvar "dimzin" sv_zp)
(print n_next)
(prin1)
)

Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius

Lien vers le commentaire
Partager sur d’autres sites

Waahoouuuu ... .. c'est super !!

 

C'est applicable à tout type d'objet (bloc, pln.. ) :)

 

Pour faire une sélection multiple, il faudrait pas mettre un (setq sv_zp (getvar "dimzin")(setq n (1- n))) ?

 

Par contre, le champ IDRACCORD est un champ texte et refuse de mettre un chiffre seul, le texte et l'alphanumérique( AD3 par exemple) fonctionnent parfaitement.

 

Le lisp me prend bien le chiffre de départ (2000 par exemple) et incrémente parfaitement mais ne l'inscrit pas dans le champ car INTEGER / STRING.

 

J'ai bien trouvé une astuce pour contourner ça, mais elle est quelque peu cavalière et risque de rentrer en conflit avec la BD lors de l'intégration.

 

En modifiant la table d'objet / Modifier en INTEGER / faire la manip / rebasculer la table d'objet en STRING, la valeur numérique a été convertie en texte...

 

Sinon, il est possible de créer les ID en alphanumérique (A523 par exemple) et reprendre manuellement la suppression du A.. Cette méthode sera moins violente pour les BDs...

 

En tous cas, vous m'avez gâté .... ;)

Lien vers le commentaire
Partager sur d’autres sites

C'est applicable à tout type d'objet (bloc, pln.. )

 

Oui du moment que la table de données d'objet y est attachée, ce que je ne controle absolument pas dans le code (ce que j'ai bien dit; sommaire)

 

Pour faire une sélection multiple, il faudrait pas mettre un (setq sv_zp (getvar "dimzin")(setq n (1- n))) ?

 

Non, du tout! DIMZIN me sert à avoir un formatage des réels en texte correct.

Il faut monter une boucle dans le code; je te laisse essayer...

 

 

Le lisp me prend bien le chiffre de départ (2000 par exemple) et incrémente parfaitement mais ne l'inscrit pas dans le champ car INTEGER / STRING.

Pour ce cas précis (forcer réel ou entier en texte), je ne vois que l'usage du quote inversé [AlGr]+[7è`], ou autrement forcer l'usage dans le code (Cond 'INT 'REAL 'STR)

 

Comme tu vois le code est loin d'être achevé, sécurisé.

Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius

Lien vers le commentaire
Partager sur d’autres sites

Oui du moment que la table de données d'objet y est attachée, ce que je ne contrôle absolument pas dans le code (ce que j'ai bien dit; sommaire)

 

 

Non, du tout! DIMZIN me sert à avoir un formatage des réels en texte correct.

Il faut monter une boucle dans le code; je te laisse essayer...

 

 

Pour ce cas précis (forcer réel ou entier en texte), je ne vois que l'usage du quote inversé [AlGr]+[7è`], ou autrement forcer l'usage dans le code (Cond 'INT 'REAL 'STR)

 

Comme tu vois le code est loin d'être achevé, sécurisé.

 

 

C'est parfait comme ça j'ai des types d'objets différents avec des table commune..

 

Pardon pour DIMZIN, :( , je suis en train de tester ça, j'ai fait un ssget '((0 . "INSERT") (2 . "AEP_RACCORD") (8 . "AEP_RACCORD"))) et il me sélectionne le même type d'objet d'un coup, faut j'intègre la variable dans tes parties pour qu'il incrémente automatiquement.

Lien vers le commentaire
Partager sur d’autres sites

C'est parfait comme ça j'ai des types d'objets différents avec des table commune..

 

Pardon pour DIMZIN, :( , je suis en train de tester ça, j'ai fait un ssget '((0 . "INSERT") (2 . "AEP_RACCORD") (8 . "AEP_RACCORD"))) et il me sélectionne le même type d'objet d'un coup, faut j'intègre la variable dans tes parties pour qu'il incrémente automatiquement.

Pour la boucle, je la ferais comme cela... mais je ne suis pas sur que ça convienne car tu n'es plus maître de l'ordre de l'incrémentation, à moins que l'ordre de la création des entités soient calqués sur celle de l'incrémentation...?

 

(defun c:numeroter ( / sv_zp n_ini js n ename nb nb_dec inc)
;;
;;Tapez (setq n_next nil) à la ligne de commande
;;pour faire une autre incrementation
;;
       (setq sv_zp (getvar "dimzin"))
       (setvar "dimzin" 4)
       (if (not n_next)
               (setq n_ini (getstring "\nIncrementer en débutant à [chiffre/lettre/alphanumérique]: "))
               (setq n_ini n_next)
       )
(setq js (ssget '((0 . "INSERT") (2 . "AEP_RACCORD") (8 . "AEP_RACCORD"))))
(cond
(js
	(repeat (setq n (sslength js))
		(setq ename (ssname js (setq n (1- n))))
       (cond
               ((eq (type (read n_ini)) 'INT)
                       (setq n_next (itoa (1+ (atoi n_ini))))
                       (ade_odsetfield ename "RACCORD" "IDRACCORD" 0 (atoi n_next))
               )
               ((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 "RACCORD" "IDRACCORD" 0 (atof n_next))
               )
               ((eq (type n_ini) 'STR)
                       (setq n_next (inc_txt n_ini))
                       (ade_odsetfield ename "RACCORD" "IDRACCORD" 0 n_next)
               )
       )
	)
)
)
       (setvar "dimzin" sv_zp)
       (print n_next)
       (prin1)
)

Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius

Lien vers le commentaire
Partager sur d’autres sites

Pour la boucle, je la ferais comme cela... mais je ne suis pas sur que ça convienne car tu n'es plus maître de l'ordre de l'incrémentation, à moins que l'ordre de la création des entités soient calqués sur celle de l'incrémentation...?

 

(defun c:numeroter ( / sv_zp n_ini js n ename nb nb_dec inc)
;;
;;Tapez (setq n_next nil) à la ligne de commande
;;pour faire une autre incrementation
;;
       (setq sv_zp (getvar "dimzin"))
       (setvar "dimzin" 4)
       (if (not n_next)
               (setq n_ini (getstring "\nIncrementer en débutant à [chiffre/lettre/alphanumérique]: "))
               (setq n_ini n_next)
       )
(setq js (ssget '((0 . "INSERT") (2 . "AEP_RACCORD") (8 . "AEP_RACCORD"))))
(cond
(js
	(repeat (setq n (sslength js))
		(setq ename (ssname js (setq n (1- n))))
       (cond
               ((eq (type (read n_ini)) 'INT)
                       (setq n_next (itoa (1+ (atoi n_ini))))
                       (ade_odsetfield ename "RACCORD" "IDRACCORD" 0 (atoi n_next))
               )
               ((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 "RACCORD" "IDRACCORD" 0 (atof n_next))
               )
               ((eq (type n_ini) 'STR)
                       (setq n_next (inc_txt n_ini))
                       (ade_odsetfield ename "RACCORD" "IDRACCORD" 0 n_next)
               )
       )
	)
)
)
       (setvar "dimzin" sv_zp)
       (print n_next)
       (prin1)
)

 

 

Je fais le test la semaine pro et je te tiens au courant

Lien vers le commentaire
Partager sur d’autres sites

Bonjour,

 

La sélection multiple fonctionne correctement,

 

Il me retourne un message d'erreur "; erreur: no function definition: INC_TXT", j'ai déclaré inc_txt dans la fonction, mais le message reste,

 

En supprimant la partie string, il me renvoit nil donc aucun champ renseigné,

Lien vers le commentaire
Partager sur d’autres sites

Bonjour,

 

La sélection multiple fonctionne correctement,

 

Il me retourne un message d'erreur "; erreur: no function definition: INC_TXT", j'ai déclaré inc_txt dans la fonction, mais le message reste,

 

En supprimant la partie string, il me renvoit nil donc aucun champ renseigné,

 

 

.. Maintenant il me met ce message pour tous les essais qui fonctionnaient mercredi ..; :-(

Lien vers le commentaire
Partager sur d’autres sites

Désolé, j'ai voulu faire court, donc je n'ai pas reposter dans le code pour la sélection multiple la fonction INC_TXT comme je l'avais fais pour le post #4. (comme la fonction ne subissait aucun changement, je n'ais pas joint lors du copier coller, l'intégralité du code)

 

Tu peux donc le récupérer au post #4 (du début jusqu'à la ligne non incluse (defun c:numeroter (....) et l'inserer dans la proposition #9

Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius

Lien vers le commentaire
Partager sur d’autres sites

Désolé, j'ai voulu faire court, donc je n'ai pas reposter dans le code pour la sélection multiple la fonction INC_TXT comme je l'avais fais pour le post #4. (comme la fonction ne subissait aucun changement, je n'ais pas joint lors du copier coller, l'intégralité du code)

 

Tu peux donc le récupérer au post #4 (du début jusqu'à la ligne non incluse (defun c:numeroter (....) et l'inserer dans la proposition #9

 

 

Pardon, J'avais mis à jour le lsp, c'est moi qui ait fait une mauvaise manipulation, j'avais pris d'autres commandes en lambda pour le lancer directement en ligne de commande et j'avais pas sélectionné le defun inc_txt ... :-\

 

Comme tu le présentais, on est plus maître de l'incrémentation et il applique la même valeur pour tous les objets..

 

Il me sélectionne bien les 43 objets, il me renseigne bien la valeur incrémenté par exemple a5=>a6 . mais il renseigne a6 pour tous..

 

Est ce qu'il faudrait pas mettre une boucle autour de la conditionnelle ?

Lien vers le commentaire
Partager sur d’autres sites

il me renseigne bien la valeur incrémenté par exemple a5=>a6 . mais il renseigne a6 pour tous..

 

Décidément, un oubli de ma part.

Je reposte le code complet.

 

(defun inc_txt (Txt / Boucle Decalage Val_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)
           ((= Ascii_Txt 91) 65)
           ((= Ascii_Txt 123) 97)
         )
       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
)
(defun c:numeroter ( / sv_zp n_ini js n ename nb nb_dec inc)
;;
;;Tapez (setq n_next nil) à la ligne de commande
;;pour faire une autre incrementation
;;
 (setq sv_zp (getvar "dimzin"))
 (setvar "dimzin" 4)
 (if (not n_next)
   (setq n_ini (getstring "\nIncrementer en débutant à [chiffre/lettre/alphanumérique]: "))
   (setq n_ini n_next)
 )
 (setq js (ssget '((0 . "INSERT") (2 . "AEP_RACCORD") (8 . "AEP_RACCORD"))))
 (cond
   (js
     (repeat (setq n (sslength js))
       (setq ename (ssname js (setq n (1- n))))
       (cond
         ((eq (type (read n_ini)) 'INT)
           (setq n_next (itoa (1+ (atoi n_ini))))
           (ade_odsetfield ename "RACCORD" "IDRACCORD" 0 (atoi n_next))
         )
         ((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 "RACCORD" "IDRACCORD" 0 (atof n_next))
         )
         ((eq (type n_ini) 'STR)
           (setq n_next (inc_txt n_ini))
           (ade_odsetfield ename "RACCORD" "IDRACCORD" 0 n_next)
         )
       )
       (setq n_ini n_next)
     )
   )
 )
 (setvar "dimzin" sv_zp)
 (print n_next)
 (prin1)
)

Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius

Lien vers le commentaire
Partager sur d’autres sites

nickel!!!! ça marche .. :)

 

Petite question, comment ça se fait que dans le cas d'un alphanumérique, il incrémente la lettre puis le chiffre et non les 2 en même temps? par exemple .. 2a, 2b, 2c... a2, b2, c2.. au lieu de faire 2a, 3b, 4c..

 

Le champ IDRACCORD (string), ne se renseigne pas si l'incrémentation se fait en integer,

L'astuce du quotte inversé fonctionne mais dans les cas de chiffres dans un champ lettre, je constate quelque soit la situation que l'incrémentation se fait uniquement de 0->9 et se réinitialise. Il ne passe pas vers la dizaine, est ce qu'on peut y faire quelque chose?

 

Sinon j'ai une astuce, au lieu de renseigner \1 , je renseigne \1000 et c'est ok..

 

En résumé, ça fonctionne .... :)

c'est génial..

 

Je vais pouvoir adapter aux autres formats d'objets (vannes, canalisation, branchement..)

Lien vers le commentaire
Partager sur d’autres sites

Bon si ça fonctionne, c'est le principal...

 

Une petite explication sur l'incrémentation alphanumérique.

J'ai voulu garder le principe du numérique; c'est à dire colonne des unités, colonne des dizaine, colonne des centaines ....

sauf qu'ici les colonnes peuvent être alphabétique. Donc l'incrémentation se fera toujours depuis la colonne de droite.

 

ET SURTOUT, ça demande à l'utilisateur de connaitre à peu près le nombre d'objet à décompter pour fournir la clé alphanumérique de départ. Par exemple débuter à "A00" pour aboutir "Z99" devrait permettre de dénombrer environ 2000 objets.

Par contre "A0" n'en permettra que 200 environ

 

Tu as aussi la possibilité de voir comment (gile) incrémente dans son code et de l'appliquer ici!

Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius

Lien vers le commentaire
Partager sur d’autres sites

Bon si ça fonctionne, c'est le principal...

 

ET SURTOUT, ça demande à l'utilisateur de connaitre à peu près le nombre d'objet à décompter pour fournir la clé alphanumérique de départ. Par exemple débuter à "A00" pour aboutir "Z99" devrait permettre de dénombrer environ 2000 objets.

Par contre "A0" n'en permettra que 200 environ

 

C'est ça .. dans le cas présent ce n'est pas un souci, puisque c'est moi qui contrôle les numéros d'identifiants...

 

Un grand merci à vous pour votre aide précieuse !! ;)

Lien vers le commentaire
Partager sur d’autres sites

Invité
Répondre à ce sujet…

×   Collé en tant que texte enrichi.   Coller en tant que texte brut à la place

  Seulement 75 émoticônes maximum sont autorisées.

×   Votre lien a été automatiquement intégré.   Afficher plutôt comme un lien

×   Votre contenu précédent a été rétabli.   Vider l’éditeur

×   Vous ne pouvez pas directement coller des images. Envoyez-les depuis votre ordinateur ou insérez-les depuis une URL.

×
×
  • Créer...

Information importante

Nous avons placé des cookies sur votre appareil pour aider à améliorer ce site. Vous pouvez choisir d’ajuster vos paramètres de cookie, sinon nous supposerons que vous êtes d’accord pour continuer. Politique de confidentialité