Can't pass necessary values to a MULTILEADER through VLisp

Can't pass necessary values to a MULTILEADER through VLisp

Kycau
Advocate Advocate
1,043 Views
9 Replies
Message 1 of 10

Can't pass necessary values to a MULTILEADER through VLisp

Kycau
Advocate
Advocate

Hello,

 

Bellow you will find attached a sample of an AutoCAD file, with some samples to which a command must be applied.
Let's assume that I want to performe on the middle sample my funcation "RN" (short for ReNumber).

If I hit "D", and select Multileaders from bottom to top, I get the sample from left.
It works fine.

Now, my intention is to run the command on the sample from left, and hit:
RN - R
After selecting Multileader I wish to get the variant from middle.

My 2nd intention is to run the command on the sample from left, hit
RN - U
After selecting Multileaders I wish to get the variant from right.

This is the part of code, that I'm talking about.
"DSE" is an abbreviation for company, with whose style I'm working.

((= comp_indx "DSE")
     (initget 7 "F D U R")
     (setq rn_mode (getkword "\nChoose numbering mode: [Floor-view/Details/Unnumber/Reset]"))
     (if (= rn_mode "F")
       (progn
	 (initget 7 "Y N")
	 (setq rn_mode (getkword "Do you wand to use prefix ? [Yes/No]"))
	 )
       )
     (if (= rn_mode "Y")
       (progn
	 (initget 7)
	 (setq prefix (getstring "Indicate prefix to be added to rebar-position: "))
	 )
       )
     (if (= rn_mode "D")
       (progn
	 (initget 6)
	 (setq st_letter (getstring "\nIndicate the start letter: <a>"))
	 (if (= st_letter "")
	   (setq st_letter "a")
	   )
	 )
       )
     (if (and
	   (= rn_mode "D")
	   (= (strlen st_letter) 1)
	   )
       (setq ch_indx (- (ascii st_letter) 98))
       (if (and
	     (= rn_mode "D")
	     (= (strlen st_letter) 2)
	     )
	 (setq ch_indx (+ (* (- (ascii (substr st_letter 1 1)) 96) 26)
			  (- (ascii (substr st_letter 2 1)) 98)
			  )
	       )
	 )
       )
     
     
     (setq ss (ssget '( (-4 . "<or") (0 . "multileader") (0 . "TEXT") (-4 . "or>") ) ))
     
     (setq indx 0)
     (setq ch_num 97)
     (repeat (sslength ss)
       (setq ch_indx (1+ ch_indx))
       (setq el (entget (ssname ss indx)))
       (setq acadObj (vlax-ename->vla-object (ssname ss indx)))
       (setq reb_pos
	      (vl-string-subst
		(cond
		  ((= rn_mode "R")
		   (strcat "(-)")
		   )
		  ((= rn_mode "U")
		   (strcat "")
		   )
		  ((= rn_mode "D")
		   (strcat
		     "("
		     (if (>= (/ (/ ch_indx 1.0) 26) 1)
		       (chr (+ (fix (/ (/ ch_indx 1.0) 26)) 96))
		       (chr 0)
		       )
		     (chr (+ 97 (rem ch_indx 26)))
		     ")"
		     )
		   )
		  ((= rn_mode "Y")
		   (strcat
		     "(v"
		     prefix
		     (rtos (1+ indx))
		     ")"
		     )
		   )
		  ((= rn_mode "N")
		   (strcat
		     "(v"
		     (rtos (1+ indx))
		     ")"
		     )
		   )
		  (t)
		  )
		(substr (vla-get-TextString acadObj)
			(1+ (vl-string-position 40 (vla-get-TextString acadObj)))
			(1+ (- (vl-string-position 41 (vla-get-TextString acadObj))
			       (vl-string-position 40 (vla-get-TextString acadObj))
			       ))
			)
		(vla-get-TextString acadObj)
		)
	     )
       (vla-put-TextString
	 acadObj
	 reb_pos
	 )
       (if (= (cdr (assoc 0 el)) "MULTILEADER")
	 (progn
	   (vla-put-TextLineSpacingStyle acadObj 2)
	   (vla-put-TextLineSpacingFactor acadObj 1)
	   )
	 )
       (vlax-release-object acadObj)
       (setq indx (1+ indx))
       )
     )


But in cases of RN-R and RN-U, I get errors, which I can't get rid off.

My "debugging" method is to run pieces of code step by step in Model-space. And the code works well enough step by step. But when I run the command, I get errors.
*** ERROR: bad argument type: numberp: nil ***

0 Likes
1,044 Views
9 Replies
Replies (9)
Message 2 of 10

ronjonp
Mentor
Mentor

First issue I see is here:

image.png

Then you need to make sure that "()" exists in the string before passing:

(1+ (vl-string-position 40 (vla-get-textstring acadobj)))

Maybe a check up top within the loop before proceeding:

(cond ((wcmatch (vla-get-textstring acadobj) "*(*)") "< do all your stuff>"))

I'd suggest you put your code in the VLIDE and check break on error .. then step through until no errors are found 🙂

image.png

 

0 Likes
Message 3 of 10

Luís Augusto
Advocate
Advocate

Worked here;

 

;| RN, short for Reinforcement Numbering.
	Copyright © 2018 Palamarciuc Alexandr
	This program edits specific chars, based on heir position, in texts, leaders, multileaders or dimensions.
	Input	:Selection set of entities
	Output	:Modified entities within that selection set
	|;

;=== 00 === Programm setup

(defun c:rn (
	     ;comp_indx	company index
	     /
	     getkword_msg	;message in error-routine
	     undo_flag		;toggle, to undo or not commands in case of error
	     
	     ss			;selection set
	     indx		;
	     el
	     ch_num
	     ch_indx
	     prefix
	     st_letter
	     _dxf_grcode_by_ent
	     ;HUB
	     rep_char
	     subst_mode
	     num_10
	     en
	     )
  
  
  
  ;=====INITIAL SETUP
  
  (setq olderr *error*)
  (setq osm (getvar "osmode"))
  (setq odm (getvar "dynmode"))
  
  (command "_.undo" "m")
  
  
  ;=====ERROR ROUTINE
  
  (defun *error* (errmsg)
    (if (not (member errmsg '("console break" "function cancelled")))
      (princ (strcat "*** ERROR: " errmsg " ***"))
      )
    (setq getkword_msg (strcat "do you want to undo "
			       (rtos (getvar "undomarks"))
			       " commands? [Yes/No]"
			       )
	  )
    (initget 7 "Y N")
    (setq undo_flag (getkword getkword_msg))
    (if (= undo_flag
	   "Y"
	   )
      (command "_.undo" "b")
      )
    )
  
  ;=== 20 ===
  
  (vl-load-com)
  
  (if (not comp_indx)
    (progn
      (initget 6 "DSE HUB MOM")
      (setq comp_indx (getkword "\nChoose company index: [DSE/HUB/MOM]"))
      )
    )

    (setq comp_indx "DSE") ;for Autodesk forum test pruposes.
    
  (cond
    
    ;=============================================
    ;================================================================================DSE
    ;=============================================
    
    ((= comp_indx "DSE")
     (initget 7 "F D U R")
     (setq rn_mode (getkword "\nChoose numbering mode: [Floor-view/Details/Unnumber/Reset]"))
     (if (= rn_mode "F")
       (progn
	 (initget 7 "Y N")
	 (setq rn_mode (getkword "Do you wand to use prefix ? [Yes/No]"))
	 )
       )
     (if (= rn_mode "Y")
       (progn
	 (initget 7)
	 (setq prefix (getstring "Indicate prefix to be added to rebar-position: "))
	 )
       )
     (if (= rn_mode "D")
       (progn
	 (initget 6)
	 (setq st_letter (getstring "\nIndicate the start letter: <a>"))
	 (if (= st_letter "")
	   (setq st_letter "a")
	   )
	 )
       )
     (if (and
	   (= rn_mode "D")
	   (= (strlen st_letter) 1)
	   )
       (setq ch_indx (- (ascii st_letter) 98))
       (if (and
	     (= rn_mode "D")
	     (= (strlen st_letter) 2)
	     )
	 (setq ch_indx (+ (* (- (ascii (substr st_letter 1 1)) 96) 26)
			  (- (ascii (substr st_letter 2 1)) 98)
			  )
	       )
	 )
       )
     
     
     (setq ss (ssget '( (-4 . "<or") (0 . "multileader") (0 . "TEXT") (-4 . "or>") ) ))
     
     (setq indx 0)
     (setq ch_num 97)
     (repeat (sslength ss)
       (setq ch_indx (1+ ch_indx))
       (setq el (entget (ssname ss indx)))
       (setq acadObj (vlax-ename->vla-object (ssname ss indx)))
       (setq str (vla-get-TextString acadObj))
       (if
	 (and (wcmatch str "*(*")
	      (wcmatch str "*)*")
	 )
	 (progn
	   (setq reb_pos
	      (vl-string-subst
		(cond
		  ((= rn_mode "R")
		   (strcat "(-)")
		   )
		  ((= rn_mode "U")
		   (strcat "")
		   )
		  ((= rn_mode "D")
		   (strcat
		     "("
		     (if (>= (/ (/ ch_indx 1.0) 26) 1)
		       (chr (+ (fix (/ (/ ch_indx 1.0) 26)) 96))
		       (chr 0)
		       )
		     (chr (+ 97 (rem ch_indx 26)))
		     ")"
		     )
		   )
		  ((= rn_mode "Y")
		   (strcat
		     "(v"
		     prefix
		     (rtos (1+ indx))
		     ")"
		     )
		   )
		  ((= rn_mode "N")
		   (strcat
		     "(v"
		     (rtos (1+ indx))
		     ")"
		     )
		   )
		  (t)
		  )
		(substr str
			(1+ (vl-string-position 40 str))
			(1+ (- (vl-string-position 41 str)
			       (vl-string-position 40 str)
			       ))
			)
		str
		)
	     )
	   )
	 (progn
	   (setq reb_pos
	      (strcat str
		 (cond
		  ((= rn_mode "R")
		   (strcat "(-)")
		   )
		  ((= rn_mode "U")
		   (strcat "")
		   )
		  ((= rn_mode "D")
		   (strcat
		     "("
		     (if (>= (/ (/ ch_indx 1.0) 26) 1)
		       (chr (+ (fix (/ (/ ch_indx 1.0) 26)) 96))
		       (chr 0)
		       )
		     (chr (+ 97 (rem ch_indx 26)))
		     ")"
		     )
		   )
		  ((= rn_mode "Y")
		   (strcat
		     "(v"
		     prefix
		     (rtos (1+ indx))
		     ")"
		     )
		   )
		  ((= rn_mode "N")
		   (strcat
		     "(v"
		     (rtos (1+ indx))
		     ")"
		     )
		   )
		  (t)
		  )
		)
	     )
	   )
	 )
       (vla-put-TextString
	 acadObj
	 reb_pos
	 )
       (if (= (cdr (assoc 0 el)) "MULTILEADER")
	 (progn
	   (vla-put-TextLineSpacingStyle acadObj 2)
	   (vla-put-TextLineSpacingFactor acadObj 1)
	   )
	 )
       (vlax-release-object acadObj)
       (setq indx (1+ indx))
       )
     )
       
     
    
    ;=============================================
    ;================================================================================MOM
    ;=============================================
    
    ((= comp_indx "MOM")
     (initget 7 "D")
     (setq rn_mode (getkword "\nChoose numbering mode: [Details]"))
     
     
     
     
     (setq ss (ssget '( (-4 . "<or") (0 . "multileader") (0 . "TEXT") (-4 . "or>") ) ))
     
     
     (setq indx 0)
     (setq ch_num 65)
     (repeat (sslength ss)
       (setq el (entget (ssname ss indx)))
       (if (= (cdr (assoc 0 el)) "MULTILEADER")
	 (setq _dxf_grcode_by_ent 304)
	 (setq _dxf_grcode_by_ent 1)
	 )
       ;|(if (= rn_mode "N")
(setq el
	     (subst
	       (cons
		 _dxf_grcode_by_ent
		 (vl-string-subst
		   (strcat
		     "("
		     (if (> (/ (/ indx 1.0) 26) 0)
		       (chr (+ (fix (/ (/ indx 1.0) 26)) 96))
		       (chr 0)
		       )
		     (chr (+ 96 (rem indx 26)))
		     ")"
		     )
		   "(-)"
		   (cdr (assoc _dxf_grcode_by_ent el))
		   )
		 )
	       (assoc _dxf_grcode_by_ent el)
	       el
	       )
	    )
      )|;
       (setq el
	      (subst
		(cons
		  _dxf_grcode_by_ent
		  (vl-string-subst
		    (strcat
		      "["
		      (if (>= (/ (/ indx 1.0) 26) 1)
			(chr (+ (fix (/ (/ indx 1.0) 26)) 64))
			(chr 0)
			)
		      (chr (+ 65 (rem indx 26)))
		      "]"
		      )
		    (substr (cdr (assoc _dxf_grcode_by_ent el))
			    (1+ (vl-string-position 91 (cdr (assoc _dxf_grcode_by_ent el))))
			    (1+ (- (vl-string-position 93 (cdr (assoc _dxf_grcode_by_ent el)))
				   (vl-string-position 91 (cdr (assoc _dxf_grcode_by_ent el)))
				   ))
			    )
		    (cdr (assoc _dxf_grcode_by_ent el))
		    )
		  )
		(assoc _dxf_grcode_by_ent el)
		el
		)
	     
	     )
       (entmod el)
       (if (= (cdr (assoc 0 el)) "MULTILEADER")
	 (progn
	   (vlax-put-property (vlax-ename->vla-object (cdr (assoc -1 el))) 'TextLineSpacingStyle 1)
	   (vlax-put-property (vlax-ename->vla-object (cdr (assoc -1 el))) 'TextLineSpacingFactor 1)
	   )
	 )
       (setq indx (1+ indx))
       
       )
     )
    
    ;=============================================
    ;================================================================================HUB
    ;=============================================
    
    ((= comp_indx "HUB")
     (setq ss (ssget '((0 . "dimension") (3 . "HUB_mark")) ))
     (initget 7 "S I D N + -")
     (setq subst_mode (getkword "Enter type of modification [Subst/Inc/Dec/Number/1+/1-]"))
     
     (if (= subst_mode "S")
       (progn
	 (initget 7 "0 1 2 3")
	 (setq num_char (getkword "Enter number of characters to be replaced [0/1/2/3]"))
	 (initget 7)
	 (setq rep_char (getstring "Enter new sequence of start strings"))
	 )
       )
     
     (if (= subst_mode "I")
       (progn
	 (initget 7)
	 (setq num_10 (getint "Enter number of 10x to increase numbering by"))
	 )
       )
     
     (if (= subst_mode "D")
       (progn
	 (initget 7)
	 (setq num_10 (getint "Enter number of 10x to decrease numbering by"))
	 )
       )
     (if (= subst_mode "N")
       (progn
	 (initget 4)
	 (setq num_10 (getint "Enter \"deca\" rank of numbering: "))
	 (if (not num_10)
	   (setq num_10 0)
	   )
	 )
       )
     
     ;30====Selection set's creation
     
     (setq indx -1)
     (repeat (sslength ss)
       (setq indx (1+ indx))
       (setq en (ssname ss indx))
       (setq el (entget en))
       
       ;40==== SUBSTITUTE
       
       (if (= subst_mode "S")
	 (entmod
	   (subst
	     (cons 1 (strcat
		       rep_char
		       (substr
			 (cdr (assoc 1 el))
			 (+ (atoi num_char) 1)
			 )
		       )
		   )
	     (assoc 1 el)
	     el
	     )
	   )
	 )
       
       ;===== INCREASE
       
       (if (= subst_mode "I")
	 (entmod
	   (subst
	     (cons 1 (strcat
		       (itoa (+ (atoi (substr (cdr (assoc 1 el)) 1 (1- (strlen (cdr (assoc 1 el))))))
				num_10
				))
		       (substr (cdr (assoc 1 el))
			       (strlen (cdr (assoc 1 el)))
			       )
		       )
		   )
	     
	     (assoc 1 el)
	     el
	     )
	   )
	 )
       
       ;===== 1+
       
       (if (= subst_mode "+")
	 (progn
	   (entmod
	     (subst
	       (cons 1 (itoa (1+ (atoi (cdr (assoc 1 el))))))
	       (assoc 1 el)
	       el
	       )
	     )
	   
	   )
	 )
       
       ;===== 1-
       
       (if (= subst_mode "-")
	 (progn
	   (entmod
	     (subst
	       (cons 1 (itoa (1- (atoi (cdr (assoc 1 el))))))
	       (assoc 1 el)
	       el
	       )
	     )
	   
	   )
	 )
       
       ;==== DECREASE
       
       (if (= subst_mode "D")
	 (progn
	   (entmod
	     (subst
	       (cons 1 (strcat
			 (itoa (- (atoi (substr (cdr (assoc 1 el)) 1 (1- (strlen (cdr (assoc 1 el))))))
				  num_10
				  ))
			 (substr (cdr (assoc 1 el))
				 (strlen (cdr (assoc 1 el)))
				 )
			 )
		     )
	       
	       (assoc 1 el)
	       el
	       )
	     )
	   (if (<= (- (atoi (substr (cdr (assoc 1 el)) 1 (1- (strlen (cdr (assoc 1 el))))))
		      num_10
		      )
		   0)
	     (progn
	       (setq errmsg "Rebar number is negative")
	       (quit)
	       )
	     )
	   )
	 )
       
       ;==== Number
       
       (if (= subst_mode "N")
	 (entmod
	   (subst
	     (cons 1 (rtos (1+ (+ indx (* num_10 10))))
		   )
	     (assoc 1 el)
	     el
	     )
	   )
	 )
       
       )
     )
    (t)
    )
  (princ)
  
  )
  
  
0 Likes
Message 4 of 10

ronjonp
Mentor
Mentor

@Luís Augusto

;; This
(and (wcmatch str "*(*") (wcmatch str "*)*"))
;; Is the same as this
(wcmatch str "*(*)*")
;; I'd recommend this to ensure the last character in the string is a closing paren
(wcmatch str "*(*)")
0 Likes
Message 5 of 10

Kycau
Advocate
Advocate

@Luís Augusto
So, all you did, is you added:

(if
(and (wcmatch str "*(*")
(wcmatch str "*)*") )
[...] )

?
It doesn't help me.
To me, it is very strange, that 
RN-D can do:
(-)(-)(-) into (a)(b)(c)
(a)(b)(c) into (c)(a)(b)

but RN-R can't do 
(a)(b)(c) into (-)(-)(-)

To me, it looks like I send to same functions, the same type of data (strings), but something goes wrong, and I can't catch it.

@ronjonpThanks for the tips. I will implement them later, when will be working on optimization )
I write routines while working as technical draftsment... and I have to keep some "simplifications", of which I am aware, and use my commands in a very specific way )
All to save precious time needed for drawing.

I use (setq indx (1+ indx)) at the end of "repeat" function.

I decided to use a second index "ch_indx", to synchronize some other data with the repeat-funcation.

P.S.
I added "(" ")" verification, and the status of my routine is the same.
RN-D does what I want to do... and RN-R and RN-U don't.

"debug"-"break on error" I checked the box, but I don't see any warnings, or highlights that point to the problematic place in my code.

-----------------
UPDATE:
Sorry, at  first there was no blue highlighting of the changes.
Now I see them.

0 Likes
Message 6 of 10

ronjonp
Mentor
Mentor



"debug"-"break on error" I checked the box, but I don't see any warnings, or highlights that point to the problematic place in my code.

I had to comment out the command calls here to step through the code. Once you effectively learn to debug in the VLIDE ( or Blade ) you'll be able to fix this yourself 🙂 Cheers!

;;;  (command "_.undo" "m")		;=====ERROR ROUTINE
  (defun *error* (errmsg)
    (if	(not (member errmsg '("console break" "function cancelled")))
      (princ (strcat "*** ERROR: " errmsg " ***"))
    )
;;;    (setq getkword_msg
;;;	   (strcat "do you want to undo " (rtos (getvar "undomarks")) " commands? [Yes/No]")
;;;    )
    (initget 7 "Y N")
    (setq undo_flag (getkword getkword_msg))
;;;    (if	(= undo_flag "Y")
;;;      (command "_.undo" "b")
;;;    )
  )
0 Likes
Message 7 of 10

Luís Augusto
Advocate
Advocate

@ronjonp

Many thanks for the tip Ron!

0 Likes
Message 8 of 10

ronjonp
Mentor
Mentor

You're welcome! 8-)

0 Likes
Message 9 of 10

Kycau
Advocate
Advocate

@Luís Augusto

I just copied all your code... and made a new .lsp file out of it.
Apploaded it in my AutoCAD.
Ran 
RN-U on (-)(-)(-) = error (should have had (-)(-)(-) deleted as result)
RN-R on (a)(b)(c) = error (should have had (-)(-)(-) as result)

I wonder if it is my local issue...

0 Likes
Message 10 of 10

Kycau
Advocate
Advocate

Sorry for your time guys.
The hard-project being finished 🙂 and a couple of day-offs... and a fresh look at my code...

I noticed that I was defining "ch_indx" only in my RN-D case.
But I was working with it always (in my RN-U and RN-R cases as well).

So, when my RN-U and RN-R came across (1+ ch_indx), it was too much for them to handle 🙂

0 Likes