Increment Attributes inserting block again

Increment Attributes inserting block again

C.Utzinger
Collaborator Collaborator
4,232 Views
63 Replies
Message 1 of 64

Increment Attributes inserting block again

C.Utzinger
Collaborator
Collaborator

HI

 

First of all: Happy New Year!!!

 

OK! I wrote this little Code, but i want to use Chars with numbers. For example EG001... EG002... EG003

 

How can i do that...????

 

 

(defun C:<Test5 ( / Pnummer)
	(princ "\nEinfügepunkt angeben: ")
	(command "_-insert" "SPI-Datenextraktionspunkt-CM" pause "1" "1" "" (setq Pnummer (getint "\nPunktnummer angeben (01): ")) "")
	(repeat 1000
	(setq Pnummer (+ Pnummer 1))
	(command "_-insert" "SPI-Datenextraktionspunkt-CM" pause "1" "1" "" Pnummer ""))	
	(prin1)
) ; end of defun
0 Likes
4,233 Views
63 Replies
Replies (63)
Message 2 of 64

ВeekeeCZ
Consultant
Consultant
Accepted solution

Hi, Happy new year you too...

 

Your issue is that you have to much of "" - erase the last one on both lines.

 

(defun C:<Test5 ( / Pnummer)
	(princ "\nEinfügepunkt angeben: ")
	(command "_-insert" "SPI-Datenextraktionspunkt-CM" pause "1" "1" "" (setq Pnummer (getint "\nPunktnummer angeben (01): ")))
	(repeat 1000
	(setq Pnummer (+ Pnummer 1))
	(command "_-insert" "SPI-Datenextraktionspunkt-CM" pause "1" "1" "" Pnummer))	
	(prin1)
) ; end of defun

 

And here is little improved version. It remembers the last number...

 

(defun C:<Test5 ( / next :AddLeadingZeros)
  
  (defun :AddLeadingZeros (a d / b) ;add zeros to 'd' many digits  ;a string
    (strcat (substr "000000000" 1 (if (>= d (setq b (strlen (itoa (fix (atof a)))))) (- d b) 0)) a))
  
  (while T
    (command "_-insert" "SPI-Datenextraktionspunkt-CM")
    (princ "\nEinfügepunkt angeben: ")
    (command pause "1" "1" ""
             (strcat "EG"
                     (:AddLeadingZeros
                       (itoa (setq *<test5-i* (if next
                                                (1+ *<test5-i*)
                                                (cond ((getint (strcat "\nPunktnummer angeben <"
                                                                       (itoa (setq next T
                                                                                   *<test5-i* (if *<test5-i*
                                                                                                (1+ *<test5-i*)
                                                                                                1)))
                                                                       ">: ")))
                                                      (*<test5-i*)))))
                     3))))
)

 

0 Likes
Message 3 of 64

C.Utzinger
Collaborator
Collaborator

Thank you i will try it

 

The "" were because te Attribute is an MText with shadow.

 

 

Regards

0 Likes
Message 4 of 64

C.Utzinger
Collaborator
Collaborator

 

It works fine, but I would like to add de Chars also one time at the beginning. In the following code it asks again and again for the Chars...

 

Could you fix it for me?

 

 

(defun C:<Test5 ( / next :AddLeadingZeros)
  
  (defun :AddLeadingZeros (a d / b) ;add zeros to 'd' many digits  ;a string
    (strcat (substr "000000000" 1 (if (>= d (setq b (strlen (itoa (fix (atof a)))))) (- d b) 0)) a))
  
  (while T
    (command "_-insert" "SPI-Datenextraktionspunkt-CM")
    (princ "\nEinfügepunkt angeben: ")
    (command pause "1" "1" ""
             (strcat (getstring "\nGeschoss (U1/EG/O1): ")
                     (:AddLeadingZeros
                       (itoa (setq *<test5-i* (if next
                                                (1+ *<test5-i*)
                                                (cond ((getint (strcat "\nPunktnummer angeben <"
                                                                       (itoa (setq next T
                                                                                   *<test5-i* (if *<test5-i*
                                                                                                (1+ *<test5-i*)
                                                                                                1)))
                                                                       ">: ")))
                                                      (*<test5-i*)))))
                     3)) ""))
)
0 Likes
Message 5 of 64

C.Utzinger
Collaborator
Collaborator

I have it now like this:

 

(defun C:<Test5 ( / next :AddLeadingZeros)
  
  (defun :AddLeadingZeros (a d / b) ;add zeros to 'd' many digits  ;a string
    (strcat (substr "000000000" 1 (if (>= d (setq b (strlen (itoa (fix (atof a)))))) (- d b) 0)) a))
  
  (if (not Gesch)
	(setq Gesch (getstring "\nGeschoss (U1/EG/O1): "))
	)
  (prin1)

  (defun *error* (errmsg)
    	(if (not (wcmatch errmsg "Function cancelled,quit / exit abort,console break"))
      	   (princ (strcat "\nError: " errmsg)))
    	(princ "\nLetzte Punktnummer gespeichert! ")
    	(princ))

  (while T
    (command "_-insert" "SPI-Datenextraktionspunkt-CM")
    (princ "\nEinfügepunkt angeben: ")
    (command pause "1" "1" ""
	   (strcat Gesch
                     (:AddLeadingZeros
                       (itoa (setq *<test5-i* (if next
                                                (1+ *<test5-i*)
                                                (cond ((getint (strcat "\nPunktnummer angeben <"
                                                                       (itoa (setq next T
                                                                                   *<test5-i* (if *<test5-i*
                                                                                                (1+ *<test5-i*)
                                                                                                1)))
                                                                       ">: ")))
                                                      (*<test5-i*)))))
                     3)) ""))
)

 

So it works. Just one more Thing. When i insert again new block it would be fine if it not will ask again for the numbers, just continuous with the next higher.

0 Likes
Message 6 of 64

ВeekeeCZ
Consultant
Consultant
Accepted solution

Your prefix prompt... if its limited just for those types, it's better getkword with "clickable" choices defined by (initget)

 

(if (not Gesch)
   (progn
     (initget 1 "U1 EG O1")
     (setq Gesch (getkword "\nGeschoss [U1/EG/O1]: "))
     ))

@c.utzinger wrote:

.... Just one more Thing. When i insert again new block it would be fine if it not will ask again for the numbers, just continuous with the next higher.


Hmm... It should be rewritten from the scratch... Post that block and I can see later what I can do - if anyone will not step-in in a meantime.

But even if we check all the current blocks for a maximum, user should have get a choice to change that.

0 Likes
Message 7 of 64

C.Utzinger
Collaborator
Collaborator

HI

 

Thank you for the Iniget, but there are more types, or the user can also write EG-001 or what they want.

 

Yes your wright with the numbers, the choice will be good.

 

 

Thank you very much!

0 Likes
Message 8 of 64

C.Utzinger
Collaborator
Collaborator

HI again

 

Is it possible Change it so you can insert the block, it asks for "EG" than for Number and then continue with the Loop?

 

Now it ask just once for "EG" and not again.

 

I had it like this but then it ask every time i insert a block for the "EG":

 

(defun C:<Test5 ( / next)
	(command "-layer" "_m" "-I-Koordinatenpunkte" "_co" "3" "-I-Koordinatenpunkte" "_l" "continuous" "-I-Koordinatenpunkte" "")  

  (defun *error* (errmsg)
    	(if (not (wcmatch errmsg "Function cancelled,quit / exit abort,console break"))
      	   (princ (strcat "\nError: " errmsg)))
    	(princ "\nLetzte Punktnummer gespeichert! ")
    	(princ))

  (while T
    (command "_-insert" "SPI-Datenextraktionspunkt-CM")
    (princ "\nEinfügepunkt angeben: ")
    (command pause "1" "1" ""
	   
           (strcat (setq Gesch (getstring "\nGeschoss angeben (U1/EG/O2): "))
                       (itoa (setq *<test5-i* (if next 
                                                (1+ *<test5-i*)
                                                (cond ((getint (strcat "\nPunktnummer angeben <"
                                                                       (itoa (setq next T
                                                                                   *<test5-i* (if *<test5-i*
                                                                                                (1+ *<test5-i*)
                                                                                                1)))
                                                                       ">: ")))
                                                      (*<test5-i*)))))
                     ) ""))
)

 

If you can see, i eliminated at the moment the zeros, i will use it later...

0 Likes
Message 9 of 64

ВeekeeCZ
Consultant
Consultant

@c.utzinger wrote:

HI again

 

Is it possible Change it so you can insert the block, it asks for "EG" than for Number and then continue with the Loop?

yes, I was about to do that myself...

 

Now it ask just once for "EG" and not again.

I had it like this but then it ask every time i insert a block for the "EG":

 

If you would localize your Gesch variable, it wound be enough... it starts with nil value each time you run the routine. I my new version i used a different approach - witch global variables. For global variables I use a complex name to not be able be in conflict with any other routine using global variables.

 

If you can see, i eliminated at the moment the zeros, i will use it later...

I get it back just because you to have most complex solution which you can erasing from.

 

About initget...

If you have given options, use (getkword). If not - you have free case, use (getstring). But key-words defined by (initget) you can use with both.

 


 

(vl-load-com)

(defun c:<Test5 ( / *error* lay :MaxAttValue :AddLeadingZeros flag)
  
  (defun *error* (errmsg)
    (if (not (wcmatch errmsg "Function cancelled,quit / exit abort,console break"))
      (princ (strcat "\nError: " errmsg)))
    (setvar 'CLAYER lay)
    (princ "\nLetzte Punktnummer gespeichert! ")
    
    (princ))
  
  (defun :MaxAttValue (pre / mxm i en em val att)
    (setq mxm 0)
    (if (setq ss (ssget "_X" (list '(0 . "INSERT") '(2 . "SPI-Datenextraktionspunkt-CM") (cons 410 (getvar 'CTAB)))))
      (repeat (setq i (sslength ss))
        (setq en (ssname ss (setq i (1- i))))
        (while (/= (cdr (assoc 0 (setq em (entget (setq en (entnext en)))))) "SEQEND")
          (and (eq (cdr (assoc 0 em)) "ATTRIB")
               (setq att (cdr (assoc 1 (reverse em))))
               (vl-string-search pre att)
               (setq val (substr att (+ 1 (vl-string-search pre att) (strlen pre))))
               (setq mxm (max mxm (atoi val)))
               ))))
    mxm)
  
  (defun :AddLeadingZeros (a d / b) ;add zeros to 'd' many digits  ;a string
    (strcat (substr "000000000" 1 (if (>= d (setq b (strlen (itoa (fix (atof a)))))) (- d b) 0)) a))
  
  
  ; ------------------------------------------------------------------------------------------------------
  
  (setq lay (getvar 'CLAYER))
  (command "_.-LAYER" "_m" "-I-Koordinatenpunkte" "_co" "3" "-I-Koordinatenpunkte" "")
  
  (or *<test5-g*
      (setq *<test5-g* ""))
  (initget "U1 EG O1")
  (setq flag (getstring (strcat "\nGeschoss angeben [U1/EG/O1] <" *<test5-g* ">: "))
        *<test5-g* (if (= flag "")
                     *<test5-g*
                     flag))
  
  (setq *<test5-i* (1+ (:MaxAttValue *<test5-g*))
        *<test5-i* (cond ((getint (strcat "\nPunktnummer angeben <" (itoa *<test5-i*) ">: ")))
                         (*<test5-i*)))
  
  (while T
    (command "_.-INSERT" "SPI-Datenextraktionspunkt-CM")
    (princ "\nEinfügepunkt angeben: ")
    (command PAUSE "1" "1" ""
             (strcat *<test5-g* (:AddLeadingZeros (itoa *<test5-i*) 3))
             "")
    (setq *<test5-i* (1+ *<test5-i*)))
)

 

0 Likes
Message 10 of 64

C.Utzinger
Collaborator
Collaborator

WOW that's amazing!

 

Just one Problem i have found... After you have choosen a "Geschoss" (EG). You can choose another for example "U1" but you can not omitting the "Geschoss", I mean only put numbers like "001 002 003...".

 

The first time it works.

 

 

Thank you 

0 Likes
Message 11 of 64

ВeekeeCZ
Consultant
Consultant
Accepted solution

I know that...your testing is too good... That's the issue with (getstring)... now I've used a little trick with getkword... - you still can enter any character.

 

But still, if there is some <last choice>, you cannot simply type nothing and ENTER for NO-prefix option. - only if you get it empty like this <>, then you can hit ENTER. Otherwise type "None", or select "None".

 

BTW your formatted MTEXT attribute give me a little hard time - so don't change the format of text inside of MTEXT - you may loos a max value recognition (especially with no prefix). The format is a part of a string value, see "\\W0.7000;EG001" Actual value is bold.

 

(vl-load-com)

(defun c:<Test5 ( / *error* lay cmd :MaxAttValue :AddLeadingZeros txt)
  
  (defun *error* (errmsg)
    (if (not (wcmatch errmsg "Function cancelled,quit / exit abort,console break"))
      (princ (strcat "\nError: " errmsg)))
    (setvar 'CLAYER lay)
    (setvar 'CMDECHO cmd)
    (princ "\nLetzte Punktnummer gespeichert!")
    (terpri)
    (princ))
  
  (defun :MaxAttValue (pre / mxm i en em val att)
    (setq mxm 0)
    (if (= pre "") (setq pre ";"))
    (if (setq ss (ssget "_X" (list '(0 . "INSERT") '(2 . "SPI-Datenextraktionspunkt-CM") (cons 410 (getvar 'CTAB)))))
      (repeat (setq i (sslength ss))
        (setq en (ssname ss (setq i (1- i))))
        (while (/= (cdr (assoc 0 (setq em (entget (setq en (entnext en)))))) "SEQEND")
          (and (eq (cdr (assoc 0 em)) "ATTRIB")
               (setq att (cdr (assoc 1 (reverse em))))
               (vl-string-search pre att)
               (setq val (substr att (+ 1 (vl-string-search pre att) (strlen pre))))
               (setq mxm (max mxm (atoi val)))
               ))))
    mxm)
  
  (defun :AddLeadingZeros (a d / b) ;add zeros to 'd' many digits  ;a string
    (strcat (substr "000000000" 1 (if (>= d (setq b (strlen (itoa (fix (atof a)))))) (- d b) 0)) a))
  
  
  ; ------------------------------------------------------------------------------------------------------
  
  (setq lay (getvar 'CLAYER)
        cmd (getvar 'CMDECHO))
  (setvar 'CMDECHO 0)
  (command "_.-LAYER" "_m" "-I-Koordinatenpunkte" "_co" "3" "-I-Koordinatenpunkte" "")
  
  (or *<test5-g*
      (setq *<test5-g* "None"))
  (initget 128 "U1 EG O1 None")
  (setq *<test5-g* (cond ((getkword (strcat "\nGeschoss angeben [U1/EG/O1/None] <" *<test5-g* ">: ")))
                         (*<test5-g*))
        *<test5-g* (if (= *<test5-g* "None")
                     ""
                     *<test5-g*))
  
  (setq *<test5-i* (1+ (:MaxAttValue *<test5-g*))
        *<test5-i* (cond ((getint (strcat "\nPunktnummer angeben <" (itoa *<test5-i*) ">: ")))
                         (*<test5-i*)))
  
  (while T
    (command "_.-INSERT" "SPI-Datenextraktionspunkt-CM")
    (princ (strcat "\nEinfügepunkt angeben für '" (setq txt (strcat *<test5-g* (:AddLeadingZeros (itoa *<test5-i*) 3))) "': "))
    (command PAUSE "1" "1" "" txt "")
    (setq *<test5-i* (1+ *<test5-i*)))
)

 

0 Likes
Message 12 of 64

C.Utzinger
Collaborator
Collaborator

WOW!!

 

Thank you very much for your time...

 

 

Kind regards

0 Likes
Message 13 of 64

C.Utzinger
Collaborator
Collaborator

Hi

 

A little question.

 

For what is the variable CMDECHO for in this case?

 

 

Kind Regards

 

Christian

0 Likes
Message 14 of 64

ВeekeeCZ
Consultant
Consultant

Hi,

 

CMDECHO controls whether are prompts of build-in commands echoed or not. In this case mainly by the INSERT command, but -LAYER too.

 

It's about nice and clear command line, clear prompts for user... it's echoed just your prompt "\nPunktnummer angeben <" (itoa *<test5-i*) ">: and not loads of other useless stuff from INSERT. 

 

Try yourself. Comment out ;(setvar 'CMDECHO 0) line... and see what the commandline gives you.

 

Message 15 of 64

C.Utzinger
Collaborator
Collaborator

Thank you very much

 

I will try!

 

Kind Regards

0 Likes
Message 16 of 64

C.Utzinger
Collaborator
Collaborator

HI

 

I have a question about this code.

 

Is it possible to add a undo function, so you can turn one (or more) back while you are inserting Points?

 

I tried some possibilities, but it doesn´t worked.

 

 

Thank you...

 

 

0 Likes
Message 17 of 64

ВeekeeCZ
Consultant
Consultant

Since we are inside of the INSERT function... it can't be done. We could use the (getpoint) function with the Undo option, but then we lose a dynamic preview.

 

0 Likes
Message 18 of 64

john.uhden
Mentor
Mentor

How about saving the default (from previous run) in a dictionary so that it remains between sessions?

Or in the registry so it remains for other dwgs?

John F. Uhden

0 Likes
Message 19 of 64

ВeekeeCZ
Consultant
Consultant

@john.uhden wrote:

How about saving the default (from previous run) in a dictionary so that it remains between sessions?

Or in the registry so it remains for other dwgs?


I have no idea what you're talking about... But feel free to add this into the code. Looking forward to!

0 Likes
Message 20 of 64

C.Utzinger
Collaborator
Collaborator

 

The preview in this case is just a little point, the text comes after clicking.

 

So it could be without the preview...?

0 Likes