Jump to content

Bad argument type: I guess I'm overseeing something elemental


Ament

Recommended Posts

Hello together,

 

I'm writing a small lisp and get the following problem:

 

If I put the name of my selection set directly to my sslength its working fine, but I'm in a loop, so I would like to put a changing variable but it doesn't accept it. Please see AutoCAD response below.

 

Command: (sslength SELC2)
41
Command: (sslength (read(strcat "SEL" ENT)))
; Error: Bad argument type: lselsetp SELC2
Command: !ENT
"C2"

From my limited understanding both expressions should give the same result what clearly is not the case. What do I have to change to make it happen?

 

Thanks for your help!

Link to comment
Share on other sites

sslength expects an ssget object. (read does not provide this.

 

I see what you are trying to do: make a string that spells SELC2 expecting it to refer to the variable SELC2.

 

(notice: you can do this in php, they call it "variable variable".

$myvar = "Hello World!"; $a = "myvar"; print $$a; => will print "Hello World!")

 

I don't know how to do this in lisp. I would like to know this myself, if anybody has an answer.

 

Can you tell us more about that loop? What are you making? Maybe other solutions exist

Edited by Emmanuel Delay
Link to comment
Share on other sites

Well, it's a bit hard to explain. I'm trying to count the number of occurences of blocks in my drawing and store the result to an individual variable. This variable is later used to put it into a table. ut unfortunately I'm struggeling at the very first steps to count the occurences in a foreach loop. Below you'll find the code:

 

(defun C:TEST ()
(setq CCLIST (list "C2" "CC" "CS1" "OFF" "PS1" "PS2" "SO"))
(foreach ENT CCLIST
(set (read(strcat "SEL" ENT)) (ssget "_X" (list (cons 0 "INSERT") (cons 2 (strcat "*_" ENT "_*")))))
(set (read(strcat "NO" ENT)) (sslength (read(strcat "SEL" ENT))))
)
)

 

 

If it was working as i expect I would be able to type !NOC2 or !NOOFF into my command bar in AutoCAD and get the amount of blocks in my drawing which have the strings _C2_ and _OFF_ inside their name. This variables will be used later in the code to be written ;)

Link to comment
Share on other sites

I guess my issue might be that there are some values in the list where no corresponding block can be found so that the ssget is nil. That makes the sslength run into an issue. I'll keep testing.

Link to comment
Share on other sites

Why don't you store these values in a list? The approach you're taking is very atypical.

(defun c:test (/ r s)
 (foreach str '("C2" "CC" "CS1" "OFF" "PS1" "PS2" "SO")
   (setq r
   (cons (cons str
	       (if (setq s (ssget "_X" (list '(0 . "INSERT") (cons 2 (strcat "*_" str "_*")))))
		 (sslength s)
		 0
	       )
	 )
	 r
   )
   )
 )
 (if r
   (print (reverse r))
   (print "No data...")
 )
 (princ)
)
;; Returns
;; (("C2" . 0) ("CC" . 0) ("CS1" . 0) ("OFF" . 0) ("PS1" . 0) ("PS2" . 0) ("SO" . 0))

Edited by ronjonp
Link to comment
Share on other sites

I'll store the names of the variables NOxx in a list in case it was created. As I said, it's just the beginning of a longer macro ;) I solved my issue using the following code.

 

 

 

(defun C:CABIN ()
(setq CCLIST (list "C2" "CC" "CS1" "OFF" "PS1" "PS2" "SO"))
(foreach ENT CCLIST
(if (setq SSENT (ssget "_X" (list (cons 0 "INSERT") (cons 2 (strcat "*_" ENT "_*")))))
(progn
(set (read(strcat "NO" ENT)) (sslength SSENT))
);progn
);if
);foreach
);defun

 

 

Now I'll put other stuff into the progn container to go ahead ;)

 

Thank you for your suggestions.

Link to comment
Share on other sites

You would be better of using ronjonp list method than setting a variable you just use the addrow method to a table as you read the list a simple double nth to put all the details into a table. If you need help with the table bit post. A side note working on project any blocks any number of attributes dynamic table width does count and supports up to 2 deep attribute totalling Door silver handle5 =10 v's Door silver handle6 =8

 

Can you post a sample dwg I need some real dwgs to work on. Can change my ssget to yours.

 

here is a start for you

(defun addsels (  ss1 / x)
(repeat (setq x (sslength ss1))
(setq ss  (ssadd (ssname ss1 (setq x (- x 1) ))ss))
)
)

; to be 
; 4 choices a hard code list 
; a select from all blocks dcl
; select from file
; pick block-s

(setq CCLIST (list "C2" "CC" "CS1" "OFF" "PS1" "PS2" "SO" "aaa" "BBB")) ; aaa BBB for testing
(setq ss  (ssadd))
(foreach ENT CCLIST
(if  (=(setq SSENT (ssget "_X" (list (cons 0 "INSERT") (cons 2 (strcat "*_" ENT "_*")))))nil)
(alert  (strcat "missing " ent))
(addsels ssent )
)
)

;;;;;; starts here
(setq lst '())
;(setq ss (ssget '((0 . "insert"))))

(repeat (setq  x (sslength ss))
(setq lst2 '())
(setq obj (vlax-ename->vla-object (ssname ss (setq x (- x 1)))))
(if (and (vlax-property-available-p obj "hasattributes")
(setq atts (vlax-invoke obj "getattributes"))
)
(progn
(setq lst2 (cons (vla-get-EffectiveName obj) lst2))
(foreach att atts
(setq lst2 (cons (vla-get-textstring att) lst2))
)
(setq lst (cons (reverse lst2) lst))
)
)
)

Edited by BIGAL
Link to comment
Share on other sites

Hello together,

 

I'm writing a small lisp and get the following problem:

 

If I put the name of my selection set directly to my sslength its working fine, but I'm in a loop, so I would like to put a changing variable but it doesn't accept it. Please see AutoCAD response below.

 

Command: (sslength SELC2)
41
Command: (sslength (read(strcat "SEL" ENT)))
; Error: Bad argument type: lselsetp SELC2
Command: !ENT
"C2"

From my limited understanding both expressions should give the same result what clearly is not the case. What do I have to change to make it happen?

 

(sslength (eval (read (strcat "SEL" ENT))))

Link to comment
Share on other sites

Ah, cool. LISP has eval too :)

 

Just know that some people are not the biggest fans

eval_is_evil_script_happens_t_shirt-rb832d959a4e9441ba1cbbd8bf4eb497d_jyr6t_1024.jpg?max_dim=325

 

I even found a lisp (not Autocad) T-shirt of it

repl_t_shirt-r7faf55a3154f47b492b1160f0874adb2_k2gm8_1024.jpg?max_dim=325

Link to comment
Share on other sites

I'll store the names of the variables NOxx in a list in case it was created. As I said, it's just the beginning of a longer macro ;) I solved my issue using the following code.

 

 

 

(defun C:CABIN ()
(setq CCLIST (list "C2" "CC" "CS1" "OFF" "PS1" "PS2" "SO"))
(foreach ENT CCLIST
(if (setq SSENT (ssget "_X" (list (cons 0 "INSERT") (cons 2 (strcat "*_" ENT "_*")))))
(progn
(set (read(strcat "NO" ENT)) (sslength SSENT))
);progn
);if
);foreach
);defun

 

 

Now I'll put other stuff into the progn container to go ahead ;)

 

Thank you for your suggestions.

 

Are you familiar with ASSOC?

;; Simple helper function
(defun _get (key l)(cdr (assoc key l)))
(setq l '(("C2" . 0) ("CC" . 0) ("CS1" . 0) ("OFF" . 88) ("PS1" . 0) ("PS2" . 0) ("SO" . 0)))
(_get "OFF" l)
;; Returns 88

Link to comment
Share on other sites

Are you familiar with ASSOC?

;; Simple helper function
(defun _get (key l)(cdr (assoc key l)))
(setq l '(("C2" . 0) ("CC" . 0) ("CS1" . 0) ("OFF" . 88) ("PS1" . 0) ("PS2" . 0) ("SO" . 0)))
(_get "OFF" l)
;; Returns 88

 

I couldn't agree more - it's curious the number of developers starting out in AutoLISP who opt for using individual variables over lists.

(defun CabinList ( l )
   (mapcar
      '(lambda ( x / s )
           (if (setq s (ssget "_X" (list '(0 . "INSERT") (cons 2 (strcat "*_" x "_*")))))
               (cons x (sslength s))
               (cons x 0)
           )
       )
       l
   )
)

(defun c:cabin ( / lst qry )
   (setq lst (CabinList '("C2" "CC" "CS1" "OFF" "PS1" "PS2" "SO"))
         qry (strcase (getstring "\nEnter a code to find the quantity <all>: "))
   )
   (if (= "" qry)
       (foreach itm lst (princ (strcat "\n" (car itm) ": " (itoa (cdr itm)))))
       (princ (strcat "\n" qry ": " (itoa (cond ((cdr (assoc qry lst))) (0)))))
   )
   (princ)
)

Link to comment
Share on other sites

Like you lee I have added a lot to my block extraction lisp being developed and use a list and double sorts on the list to work out the block counts 2 attributes deep. this post inspired me to add just this option to it a predefined group of block names including wildcard support.

 

Ament run the code I posted and you will see a list of all the blocks.

Link to comment
Share on other sites

I couldn't agree more - it's curious the number of developers starting out in AutoLISP who opt for using individual variables over lists.

 

I expect that it's because most of us start as Draft-persons with a familiarity with basic (or should I say "BASIC") programming and no exposure to list manipulation. If you were to take a poll you'd probably find most of us have a tendency to only do programming very occasionally and possibly only after searched diligently for someone else's solution first :).

Link to comment
Share on other sites

I expect that it's because most of us start as Draft-persons with a familiarity with basic (or should I say "BASIC") programming and no exposure to list manipulation. If you were to take a poll you'd probably find most of us have a tendency to only do programming very occasionally and possibly only after searched diligently for someone else's solution first :).

LISt Processing is what you need to learn to do :)

 

IMO this snippet below is much simpler than what the OP is doing ... but without seeing the end result it's hard to tell. Maybe these globals are used as a lisp variable field? %%

;; Simple helper function
(defun _get (key l)(cdr (assoc key l)))
(setq l '(("C2" . 0) ("CC" . 0) ("CS1" . 0) ("OFF" . 88) ("PS1" . 0) ("PS2" . 0) ("SO" . 0)))
(_get "OFF" l)
;; Returns 88

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...