Jump to content

Draw the BBox for certain block - why I get "too many arguments error"?


Grrr

Recommended Posts

Hi guys,

 

I'm trying my best and still don't understand why I get this error:

Error: too many arguments

 

The code supposes to filter selection by certain dynamic block with name "VLD_РАМКА_V2" and then draw the boundingbox around each selected block object with that name:

 

; Make a selection and filter certain block by its effective name
; Get and draw the boundingbox around each block object

(defun c:test (/ blkname found objs ss name blk vlst ovar minpt maxpt crds)
(if 
	(and 
		(not
			(setq blkname "VLD_РАМКА_V2") ;<-BLOCK NAME
			(princ "\nSelect objects" )
			(setq found (tblsearch "BLOCK" blkname))
			(setq objs (ssadd))
			(setq ss   (ssget "_:L" '((0 . "INSERT"))))
		);not
	);and
	(progn
		(repeat
			(setq i (sslength ss))
			(setq name (vla-get-effectivename
				(vlax-ename->vla-object
					(setq blk (ssname ss (setq i (1- i))))
				)
			)
			)
			(if (eq (strcase blkname) (strcase name))
				(ssadd blk objs)
			)
		)
		(if objs
			(progn
				(sssetfirst nil objs) ; is this required ?
				(setq vlst '("CMDECHO" "OSMODE" "DIMASSOC")
				ovar (mapcar 'getvar vlst))
				(mapcar 'setvar vlst '(0 0 2))
				(foreach obj  (mapcar 'vlax-ename->vla-object
				(vl-remove-if 'listp (mapcar 'cadr (ssnamex objs))))
				(vla-getboundingbox obj 'minpt 'maxpt)
				(setq crds (mapcar 'vlax-safearray->list (list minpt maxpt)))
				
				(command "_.rectangle" (car crds) (cadr crds))
				
				(mapcar 'setvar vlst ovar)
				);foreach
				(princ (strcat "\nSelected " (itoa (sslength objs)) " blocks "))
			);progn
		); if objs
	);progn
	
	(cond 
		((null ss)
			(princ "\nEmpty Selection!") ;(C:test)
		)
		((not blkname)
			(princ "\n Missed name of block ***")
		)
		((not found)
			(princ "\n Block not found in drawing !!!")
		)
		(t
			(princ "\n couldn't find any block !!! ")
		)
	);cond
);if
(princ)
);defun

Link to comment
Share on other sites

I would start here

http://help.autodesk.com/view/ACD/2015/ENU/?guid=GUID-991AD6A0-61AA-45C9-8C27-CADF9F36BE71

 

Note that the 'not' function only takes one argument. You currently have five.

 

I would also take a look at your conditional

(if objs
   (progn
       ...

The symbol 'objs' points to a selection set from your previous setq.

(setq objs (ssadd))

It will still return a non-nil value even if the selection set has had no new entities added to it.

Link to comment
Share on other sites

Good morning :)

 

In addition to what Clint has pointed to, let me show you some potential mistakes that might be unclear to you.

 

Test this code:

([color="blue"]if[/color] ([color="blue"]setq [/color]objs ([color="blue"]ssadd[/color]))
 ([color="blue"]alert [/color][color="magenta"]"Variable objs has values"[/color])
 ([color="blue"]alert [/color][color="magenta"]"Variable objs doesn't have any value"[/color])
 )

 

The above codes would never return nil since the function ssadd would always have a value that you might thought it is just a declaration of a variable to add entity names to it if they match your criteria, so your statement in your proram (if objs .... would never be equal to nil and this is considered wrong and not correct way to get the desired outcome of the codes.

 

So in this case you need to check if the variable 'objs' has values that is more than one since the first return of the function ssadd would have one selection set.

 

This code which is included into your cond function would NEVER return nil since the variable 'blkname' has value which is the original block name (string type) so the next expression of cond function would never be reached.

(([color="blue"]not [/color]blkname) ......

 

The following codes included into the foreach function which mean that only the first bounding box would be draw correctly into its position and the rest would not since the system variable OSMODE would be back to it original setting.

(mapcar '[color="blue"]setvar [/color]vlst ovar)

 

One last thing to pay your attention to is that you already have the vla-object when you check for the block name so just add that vla-object of the entity name to a variable instead of retrieving them once again with the use of ssnamex function which is an extra iteration of the same objects that you can do without.

 

Hope this would not let you down but encourage you to be aware of them into your next program.

 

Happy coding.

Link to comment
Share on other sites

Thanks alot guys!

By following Clint's advices I managed to fix the main problems.

 

Hi, Tharwat :)

(if (setq objs (ssadd))
 (alert "Variable objs has values")
 (alert "Variable objs doesn't have any value")
 )

The above codes would never return nil since the function ssadd would always have a value
So in this case you need to check if the variable 'objs' has values that is more than one since the first return of the function ssadd would have one selection set.

 

So the check must become something like this?:

(if (> (sslength objs) 1)
(alert "Variable objs has values")
(alert "Variable objs doesn't have any value")
)

 

Thanks for the other advices, but I don't completely understood that:

One last thing to pay your attention to is that you already have the vla-object when you check for the block name so just add that vla-object of the entity name to a variable instead of retrieving them once again with the use of ssnamex function which is an extra iteration of the same objects that you can do without.

To be honest I'm a bit loss as it goes with converting objects to entities and vice-versa. I just take some parts from your/LM's codes and reuse them (sorry about that but I try to learn from the best).

 

Do you have any examples how this works? I mean if entsel/nentsel or ssget is used, what type of object do we get? When its needed to be converted for usage in some other function? I just don't know where to look to understand this whole proccess.

Link to comment
Share on other sites

Hi, Tharwat :)

So the check must become something like this?:

(if (> (sslength objs) 1)
(alert "Variable objs has values")
(alert "Variable objs doesn't have any value")
)

Better to check if it is bigger than zero and NOT one, actually I just wanted to show you that when you call the function ssadd it will have value and to check if any object add to our first built of ssadd , we need to check if the number of its variable is more than zero as you have demonstrated in the above example, although you don't need it at all in your program.

 

Thanks for the other advices, but I don't completely understood that:

 

To be honest I'm a bit loss as it goes with converting objects to entities and vice-versa. I just take some parts from your/LM's codes and reuse them (sorry about that but I try to learn from the best).

 

Do you have any examples how this works? I mean if entsel/nentsel or ssget is used, what type of object do we get? When its needed to be converted for usage in some other function? I just don't know where to look to understand this whole proccess.

 

Have a look at the following mods;

 

(repeat (setq i (sslength ss))
 (setq vla-obj (vlax-ename->vla-object (setq blk (ssname ss (setq i (1- i)))))
       name    (vla-get-effectivename vla-obj)        
       )
 (if (eq (strcase blkname) (strcase name))
   (setq lst (cons vla-obj lst))
   )
 )

(if lst
 (progn
   (setq vlst '("CMDECHO" "OSMODE" "DIMASSOC")
         ovar (mapcar 'getvar vlst)
         )
   (mapcar 'setvar vlst '(0 0 2))
   (foreach obj lst
     (vla-getboundingbox obj 'minpt 'maxpt)
     (setq crds (mapcar 'vlax-safearray->list (list minpt maxpt)))
     (command "_.rectangle" "_non" (car crds) "_non" (cadr crds))
     )
   (mapcar 'setvar vlst ovar)
   )
 )

 

Do you have any examples how this works? I mean if entsel/nentsel or ssget is used, what type of object do we get? When its needed to be converted for usage in some other function? I just don't know where to look to understand this whole proccess.

 

You can find all AutoLISP functions in THIS LINK

Link to comment
Share on other sites

Thanks, Tharwat!

 

I'll check:

ssname ssnamex vlax-ename->vla-object and vlax-vla-object->ename

functions.

 

If I understand correctly there are only these 2 types:

 

Entity name (ename)

<Entity name: 27e0540>

VLA-object

<VLA-OBJECT IAcadLWPolyline 03f713a0>

That are like "physical objects" in the code and can be accepted as arguments in other functions

(as I see vla-get-effectivename requires vla-obj

and entget requires ename).

 

Sorry if I'm writing nonsense. Its hard to understand how this works.

Link to comment
Share on other sites

Yes I agree with what you have mentioned.

When you work with pure AutoLISP, you don't need any conversion to but with Vlisp and Active-X objects must be to deal with.

 

When you work with long and big programs you would notice the speed between the two types. DXF which is pure AutoLISP is faster and smoother than Vlisp codes.

Link to comment
Share on other sites

Without going any further offtopic, I'll continue reading this LISP library you posted few times in this forum.

I think that by checking each "not-well-known" function's arguments and returns I might skip the most common erros.

Have a nice evening! :)

Link to comment
Share on other sites

Concentrate on the return value of any function you are reading or using because this would help you a lot to know which way your program is intending to take. :D

 

Have a nice evening! :)

Thanks. You too. :)

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...