Jump to content

vl-catch-all-apply with lambda


Grrr

Recommended Posts

Hi guys,

I was learing about "Error Trapping" but some questions came up.

I think I understood the basics of it (by this sample code, with comments):

(defun C:test ( / SS a errCount o ll ur )
(if (not (setq SS (ssget "_I")))
	(progn
		(prompt "\nSelect objects to rotate: ")
		(setq SS (ssget "_:L"))
	)
)

(if SS
	(progn
		(sssetfirst nil nil)
		(initget 1)
		(setq a (getangle "\nSpecify rotation angle: "))
		(setq errCount 0)
		(vlax-for o (setq SS (vla-get-ActiveSelectionSet (vla-get-activedocument (vlax-get-acad-object))))
			(vla-GetBoundingBox o 'll 'ur)
			(if 
				(vl-catch-all-error-p ; determines if the value of (vl-catch-all-apply) is an error, returns T or nil
					(vl-catch-all-apply ; requires a (function) and a (list) 
						'vla-rotate ; the function (can be a lambda expression either)
						(list ; the list
							o ; <- arg (vla-object)
							(vlax-3D-point ; <- arg (safearray point)
								(mapcar '(lambda (a b) (/ (+ a b) 2.))
									(vlax-safearray->list ll)
									(vlax-safearray->list ur)
								)
							) 
							a ; <- arg (angle)
						); list
					)
				)
				(setq errCount (1+ errCount))
			); if
		); vlax-for
		(if (/= 0 errCount) (princ (strcat "\n" (itoa errCount) " objects were on locked layer!")))
		(vla-delete SS)
	);progn
); if SS
(princ)
); defun 
(vl-load-com)(princ)

However after reading the help file:

Signature

(vl-catch-all-apply 'function list)

'function

Type: Symbol

A function. The function argument can be either a symbol identifying a defun or lambda expression.

list

Type: List

A list containing arguments to be passed to the function.

Return Values

Type: Integer, Real, String, List, ads_name, T, nil, or catch-all-apply-error

... and attempting to use lambda expression on another test code:

[color=#8b4513]; the main task: trying to use [b][color=BLACK]([/color][/b]vl-catch-all-apply[b][color=BLACK])[/color][/b] with [b][color=BLACK]([/color][/b]lambda[b][color=BLACK])[/color][/b][/color]
[color=#8b4513]; the goal here is to iterate trough all layers, and return the non-active ones [b][color=BLACK]([/color][/b]couldn't figure out a better example[b][color=BLACK])[/color][/b][/color]
[b][color=BLACK]([/color][/b]defun C:test [b][color=FUCHSIA]([/color][/b] / LayersLst [b][color=FUCHSIA])[/color][/b]
[b][color=FUCHSIA]([/color][/b]vl-load-com[b][color=FUCHSIA])[/color][/b]
[color=#8b4513]; any explanation when/why [color=#2f4f4f]"Start/End UndoMark"[/color] method is used for?[/color]
[b][color=FUCHSIA]([/color][/b]vla-StartUndoMark [b][color=NAVY]([/color][/b]vla-get-ActiveDocument [b][color=MAROON]([/color][/b]vlax-get-acad-object[b][color=MAROON])[/color][/b][b][color=NAVY])[/color][/b][b][color=FUCHSIA])[/color][/b]

[b][color=FUCHSIA]([/color][/b]vlax-for lay [b][color=NAVY]([/color][/b]vla-get-Layers [b][color=MAROON]([/color][/b]vla-get-ActiveDocument [b][color=GREEN]([/color][/b]vlax-get-acad-object[b][color=GREEN])[/color][/b][b][color=MAROON])[/color][/b][b][color=NAVY])[/color][/b]
	[b][color=NAVY]([/color][/b]setq LayersLst [b][color=MAROON]([/color][/b]cons lay LayersLst[b][color=MAROON])[/color][/b][b][color=NAVY])[/color][/b]
[b][color=FUCHSIA])[/color][/b][color=#8b4513]; vlax-for[/color]
[color=#8b4513]; The main question is below:[/color]
[b][color=FUCHSIA]([/color][/b]if
	[b][color=NAVY]([/color][/b]vl-catch-all-error-p
		[b][color=MAROON]([/color][/b]vl-catch-all-apply [color=#8b4513]; will [b][color=GREEN]([/color][/b]vl-catch-all-apply[b][color=GREEN])[/color][/b] + [b][color=GREEN]([/color][/b]lambda[b][color=GREEN])[/color][/b] work for more than one list?[/color]
			'[b][color=GREEN]([/color][/b]lambda [b][color=BLUE]([/color][/b] x [b][color=BLUE])[/color][/b] [color=#8b4513]; arguments?![/color]
				[b][color=BLUE]([/color][/b]eq 
					[b][color=RED]([/color][/b]car x[b][color=RED])[/color][/b]
					[b][color=RED]([/color][/b]cadr x[b][color=RED])[/color][/b]
				[b][color=BLUE])[/color][/b][color=#8b4513]; test for the error [b][color=BLUE]([/color][/b]must be like this?[b][color=BLUE])[/color][/b][/color]
			[b][color=GREEN])[/color][/b]
			[b][color=GREEN]([/color][/b]list [color=#8b4513]; wrap 2 lists in one?[/color]
				[b][color=BLUE]([/color][/b]mapcar 'vla-get-name LayersLst[b][color=BLUE])[/color][/b]
				[b][color=BLUE]([/color][/b]list [b][color=RED]([/color][/b]vla-get-name [b][color=PURPLE]([/color][/b]vla-get-ActiveLayer [b][color=TEAL]([/color][/b]vla-get-ActiveDocument [b][color=OLIVE]([/color][/b]vlax-get-acad-object[b][color=OLIVE])[/color][/b][b][color=TEAL])[/color][/b][b][color=PURPLE])[/color][/b][b][color=RED])[/color][/b][b][color=BLUE])[/color][/b] 
			[b][color=GREEN])[/color][/b]
		[b][color=MAROON])[/color][/b]
	[b][color=NAVY])[/color][/b]
	[b][color=NAVY]([/color][/b]princ [b][color=MAROON]([/color][/b]strcat [color=#2f4f4f]"\nNot Active: "[/color] [b][color=GREEN]([/color][/b]vla-get-name [b][color=BLUE]([/color][/b]car x[b][color=BLUE])[/color][/b][b][color=GREEN])[/color][/b][b][color=MAROON])[/color][/b][b][color=NAVY])[/color][/b]
	[b][color=NAVY]([/color][/b]princ [b][color=MAROON]([/color][/b]strcat [color=#2f4f4f]"\nActive Layer: "[/color] [b][color=GREEN]([/color][/b]vla-get-name [b][color=BLUE]([/color][/b]car x[b][color=BLUE])[/color][/b][b][color=GREEN])[/color][/b][b][color=MAROON])[/color][/b][b][color=NAVY])[/color][/b]
[b][color=FUCHSIA])[/color][/b][color=#8b4513]; if[/color]

[b][color=FUCHSIA]([/color][/b]vla-EndUndoMark [b][color=NAVY]([/color][/b]vla-get-ActiveDocument [b][color=MAROON]([/color][/b]vlax-get-acad-object[b][color=MAROON])[/color][/b][b][color=NAVY])[/color][/b][b][color=FUCHSIA])[/color][/b]
[b][color=FUCHSIA]([/color][/b]princ[b][color=FUCHSIA])[/color][/b]
[b][color=BLACK])[/color][/b][color=#8b4513]; defun[/color]

I failed, simply because I don't know how to properly construct the code using vl-catch-all-apply with lambda (I even couldn't find enough good examples about it - only one post from Lee where is mentioned that there needs to be a "test for an error" inside the lambda.)

So any thoughts?

 

And a bonus question: can someone enlighten me about the Start/End UndoMark method? What it does and when/why its used?

Link to comment
Share on other sites

Hi,

 

Here is a simple example to demonstrate the use of vl-catch-all-apply & lambda functions all together;

 

([color="blue"]vl-catch-all-error-p[/color] ([color="blue"]vl-catch-all-apply[/color]
                       '([color="blue"]lambda nil[/color]
                         [color="slategray"] ;; Forced to have an error in this case since it's not possible
                          ;; to concatenate a string with a list of strings in this example.[/color]
                          ([color="blue"]strcat[/color] [color="magenta"]"Layer1" [/color]([color="blue"]mapcar [/color]'[color="blue"]vla-get-name[/color] layerslst))
                          )
                       )
 )

 

Then to know what that error message is, just replace the function vl-catch-all-error-p with this vl-catch-all-error-message

 

Hope this helps.:)

Link to comment
Share on other sites

And a bonus question: can someone enlighten me about the Start/End UndoMark method? What it does and when/why its used?

 

So with the vla-StartUndoMark function you can set a marker to where you want to undo a series of operations that are running between this function and the necessarily followed function which is vla-EndUndoMark to end or mark the end of that series of operations you have into your program, then when you in need to UNDO what you have done - you'd undo all tasks that included earlier between these two functions.

 

Run Test1 and when you finish try to undo and do the same thing with the second program Test2 to see the differences between both of them with the use of fore-said functions.

(defun c:Test1  (/ doc ins)
 (if (zerop (getvar 'pdmode))
   (setvar 'pdmode 3)
   )
 (setq doc (vla-get-activedocument (vlax-get-acad-object)))
 (repeat 3
   (if (setq ins (getpoint "\nSpecify a point :"))
     (progn
       (vla-startundomark doc)
       (entmake (list '(0 . "POINT") (cons 10 ins)))
       (vla-endundomark doc)
       )
     )
   )
 (princ)
 )
;;			;;
(defun c:Test2  (/ doc ins)
 (if (zerop (getvar 'pdmode))
   (setvar 'pdmode 3)
   )
 (setq doc (vla-get-activedocument (vlax-get-acad-object)))
 (vla-startundomark doc)
 (repeat 3
   (if (setq ins (getpoint "\nSpecify a point :"))
     (entmake (list '(0 . "POINT") (cons 10 ins)))
     )
   )
 (vla-endundomark doc)
 (princ)
 )

Link to comment
Share on other sites

Thanks for the help Tharwat!

I made a small progress upon testing the error-catching:

; if the active layer can be turned off, then lock it:
(defun C:test1 ( / ) ; Locked and turned off
(if 
	(not 
		(vl-catch-all-error-p ; if theres an error this returns T
			(vl-catch-all-apply
				'(lambda ()
					(vla-put-LayerOn (vla-get-ActiveLayer (vla-get-ActiveDocument (vlax-get-acad-object))) :vlax-false)
				)
			)
		)
	)
	(vla-put-lock (vla-get-ActiveLayer (vla-get-ActiveDocument (vlax-get-acad-object))) :vlax-true)
)
(princ)
); defun

(defun C:test2 ( / ) ; only turned off (NOT LOCKED!)
(if 
	(vla-put-LayerOn (vla-get-ActiveLayer (vla-get-ActiveDocument (vlax-get-acad-object))) :vlax-false)
	(vla-put-lock (vla-get-ActiveLayer (vla-get-ActiveDocument (vlax-get-acad-object))) :vlax-true)
)
(princ)
)

It seems that it can evaluate the result of an function, on the above code I tested 2 defuns, and wrote the result on the right side of each defun.

So this means if the property value is assigned, then return T for evaluation.

I'll continue these experiments because I feel that I still haven't found a good practical example. (usually I see people using it on iteration trough a collection object).

 

On the other hand, for the bonus question - your example really helped me understand what Start/End UndoMark does, so I wrote myself another test code about it:

[color=#8b4513]; Start-End-UndoMark Testing:[/color]
[color=#8b4513]; pick a series of entities, to draw for each one its boundingbox[/color]
[color=#8b4513]; upon undoing [b][color=BLACK]([/color][/b]ctrl+Z[b][color=BLACK])[/color][/b], the Mark type [color=#2f4f4f]"A"[/color] should undo all the created BoundingBoxes[/color]
[color=#8b4513]; upon undoing [b][color=BLACK]([/color][/b]ctrl+Z[b][color=BLACK])[/color][/b], the Mark type [color=#2f4f4f]"B"[/color] should undo one by one, every created BoundingBox[/color]
[b][color=BLACK]([/color][/b]defun C:test [b][color=FUCHSIA]([/color][/b] / AcDocForA AcDocForB ent vla-obj ll ur p1 p2 p3 p4 [b][color=FUCHSIA])[/color][/b]
[b][color=FUCHSIA]([/color][/b]vl-load-com[b][color=FUCHSIA])[/color][/b] [b][color=FUCHSIA]([/color][/b]setvar 'errno 0[b][color=FUCHSIA])[/color][/b]
[b][color=FUCHSIA]([/color][/b]or
	[b][color=NAVY]([/color][/b]setq AcDocForA [b][color=MAROON]([/color][/b]vla-get-ActiveDocument [b][color=GREEN]([/color][/b]vlax-get-acad-object[b][color=GREEN])[/color][/b][b][color=MAROON])[/color][/b][b][color=NAVY])[/color][/b] [color=#8b4513]; put semicolon here[/color]
	[b][color=NAVY]([/color][/b]setq AcDocForB [b][color=MAROON]([/color][/b]vla-get-ActiveDocument [b][color=GREEN]([/color][/b]vlax-get-acad-object[b][color=GREEN])[/color][/b][b][color=MAROON])[/color][/b][b][color=NAVY])[/color][/b] [color=#8b4513]; or put semicolon here[/color]
[b][color=FUCHSIA])[/color][/b]

[b][color=FUCHSIA]([/color][/b]if AcDocForA [b][color=NAVY]([/color][/b]vla-StartUndoMark AcDocForA[b][color=NAVY])[/color][/b][b][color=FUCHSIA])[/color][/b][color=#8b4513]; Mark type: [color=#2f4f4f]"A"[/color][/color]

[b][color=FUCHSIA]([/color][/b]while T
	[b][color=NAVY]([/color][/b]while
		[b][color=MAROON]([/color][/b]not
			[b][color=GREEN]([/color][/b]and
				[b][color=BLUE]([/color][/b]setq ent [b][color=RED]([/color][/b]car [b][color=PURPLE]([/color][/b]entsel [color=#2f4f4f]"\Pick an entity to draw its BBox: "[/color][b][color=PURPLE])[/color][/b][b][color=RED])[/color][/b][b][color=BLUE])[/color][/b]
				[b][color=BLUE]([/color][/b]setq vla-obj [b][color=RED]([/color][/b]vlax-ename->vla-object ent[b][color=RED])[/color][/b][b][color=BLUE])[/color][/b]
			[b][color=GREEN])[/color][/b]
		[b][color=MAROON])[/color][/b]
		[b][color=MAROON]([/color][/b]if [b][color=GREEN]([/color][/b]or [b][color=BLUE]([/color][/b]member [b][color=RED]([/color][/b]getvar 'errno[b][color=RED])[/color][/b] '[b][color=RED]([/color][/b]7 52[b][color=RED])[/color][/b][b][color=BLUE])[/color][/b] [b][color=BLUE]([/color][/b]null ent[b][color=BLUE])[/color][/b][b][color=GREEN])[/color][/b] [b][color=GREEN]([/color][/b]princ [color=#2f4f4f]"\nYou missed, try again!"[/color][b][color=GREEN])[/color][/b][b][color=MAROON])[/color][/b]
	[b][color=NAVY])[/color][/b][color=#8b4513]; while[/color]
	
	[b][color=NAVY]([/color][/b]if AcDocForB [b][color=MAROON]([/color][/b]vla-StartUndoMark AcDocForB[b][color=MAROON])[/color][/b][b][color=NAVY])[/color][/b][color=#8b4513]; Mark type: [color=#2f4f4f]"B"[/color][/color]
	
	[b][color=NAVY]([/color][/b]vla-GetBoundingBox vla-obj 'll 'ur[b][color=NAVY])[/color][/b]
	[b][color=NAVY]([/color][/b]setq 
		p1 [b][color=MAROON]([/color][/b]vlax-safearray->list ll[b][color=MAROON])[/color][/b]
		p2 [b][color=MAROON]([/color][/b]vlax-safearray->list ur[b][color=MAROON])[/color][/b]
		p3 [b][color=MAROON]([/color][/b]list [b][color=GREEN]([/color][/b]car p2[b][color=GREEN])[/color][/b] [b][color=GREEN]([/color][/b]cadr p1[b][color=GREEN])[/color][/b][b][color=MAROON])[/color][/b] [color=#8b4513]; lr[/color]
		p4 [b][color=MAROON]([/color][/b]list [b][color=GREEN]([/color][/b]car p1[b][color=GREEN])[/color][/b] [b][color=GREEN]([/color][/b]cadr p2[b][color=GREEN])[/color][/b][b][color=MAROON])[/color][/b] [color=#8b4513]; ul[/color]
	[b][color=NAVY])[/color][/b]
	[b][color=NAVY]([/color][/b]LWPoly-Red [b][color=MAROON]([/color][/b]list p1 p3 p2 p4[b][color=MAROON])[/color][/b] 1[b][color=NAVY])[/color][/b]
	
	[b][color=NAVY]([/color][/b]if AcDocForB [b][color=MAROON]([/color][/b]vla-EndUndoMark AcDocForB[b][color=MAROON])[/color][/b][b][color=NAVY])[/color][/b][color=#8b4513]; Mark type: [color=#2f4f4f]"B"[/color][/color]
	
[b][color=FUCHSIA])[/color][/b][color=#8b4513]; while T[/color]

[b][color=FUCHSIA]([/color][/b]if AcDocForA [b][color=NAVY]([/color][/b]vla-EndUndoMark AcDocForA[b][color=NAVY])[/color][/b][b][color=FUCHSIA])[/color][/b][color=#8b4513]; Mark type: [color=#2f4f4f]"A"[/color][/color]
[b][color=FUCHSIA]([/color][/b]princ[b][color=FUCHSIA])[/color][/b]
[b][color=BLACK])[/color][/b]

[b][color=BLACK]([/color][/b]defun LWPoly-Red [b][color=FUCHSIA]([/color][/b]lst cls[b][color=FUCHSIA])[/color][/b]
[b][color=FUCHSIA]([/color][/b]entmakex 
	[b][color=NAVY]([/color][/b]append 
		[b][color=MAROON]([/color][/b]list 
			[b][color=GREEN]([/color][/b]cons 0 [color=#2f4f4f]"LWPOLYLINE"[/color][b][color=GREEN])[/color][/b]
			[b][color=GREEN]([/color][/b]cons 100 [color=#2f4f4f]"AcDbEntity"[/color][b][color=GREEN])[/color][/b]
			[b][color=GREEN]([/color][/b]cons 100 [color=#2f4f4f]"AcDbPolyline"[/color][b][color=GREEN])[/color][/b]
			[b][color=GREEN]([/color][/b]cons 62 1[b][color=GREEN])[/color][/b]
			[b][color=GREEN]([/color][/b]cons 90 [b][color=BLUE]([/color][/b]length lst[b][color=BLUE])[/color][/b][b][color=GREEN])[/color][/b]
			[b][color=GREEN]([/color][/b]cons 70 cls[b][color=GREEN])[/color][/b]
		[b][color=MAROON])[/color][/b]
		[b][color=MAROON]([/color][/b]mapcar [b][color=GREEN]([/color][/b]function [b][color=BLUE]([/color][/b]lambda [b][color=RED]([/color][/b]p[b][color=RED])[/color][/b] [b][color=RED]([/color][/b]cons 10 p[b][color=RED])[/color][/b][b][color=BLUE])[/color][/b][b][color=GREEN])[/color][/b] lst[b][color=MAROON])[/color][/b]
	[b][color=NAVY])[/color][/b]
[b][color=FUCHSIA])[/color][/b]
[b][color=BLACK])[/color][/b]

Sorry for my late replies, I don't have much free time to reply (but enough to analyse the codes).

If I figure something out I'll post it later, And thanks again! :)

Link to comment
Share on other sites

Hi,

 

The two functions vla-put-LayerOn & vla-put-lock will ALWAYS return nil so your example with vl-catch**** does help at all in this case.

 

The following codes also will not evaluate / reach the second line so the variable 'AcDocForB' will ALWAYS be nil

 

(or
	(setq AcDocForA (vla-get-ActiveDocument (vlax-get-acad-object))) 
	(setq AcDocForB (vla-get-ActiveDocument (vlax-get-acad-object))) 
)

Link to comment
Share on other sites

Hi again, Tharwat

The two functions vla-put-LayerOn & vla-put-lock will ALWAYS return nil so your example with vl-catch**** does help at all in this case.

Thanks, now I see that I was wrong about this... just wanted to ask you, do you checked them in the console like this? :

_$ (not 
		(vl-catch-all-error-p ; if theres an error this returns T
			(vl-catch-all-apply
				'(lambda ()
					(vla-put-LayerOn (vla-get-ActiveLayer (vla-get-ActiveDocument (vlax-get-acad-object))) :vlax-false)
				)
			)
		)
	)
T
_$ (vla-put-LayerOn (vla-get-ActiveLayer (vla-get-ActiveDocument (vlax-get-acad-object))) :vlax-false)
nil
_$ 

I'm still kinda greenish when it comes about returns and evaluations.

However, I did a BUNCH of test codes regarding vl-catch-*** functions and in some cases lambda, so here are few with the printed results:

(defun C:test ( / mixLst newLst errCnt ) ; <- TESTED and WORKS ! (results are commented below)
; construct a list, containing items of different type:
(setq mixLst (list 10 "twenty" "thirty" 40 50 (list "sixty") 70 "eighty" 90 (list "one hundred")))

(foreach itm mixLst
	(if 
		(not 
			(vl-catch-all-error-p ; if theres an error this returns T
				(vl-catch-all-apply
					'(lambda nil
						(or ; put semicolons where needed here:
							(rtos itm)
							(strcat itm)
							(/ itm 2.)
						); or
					)
				)
			)
		)
		(setq newLst (cons itm newLst)) ; no error occured
		(progn ; an error occured 
			(if (not errCnt) (setq errCnt 0))
			(setq errCnt (1+ errCnt))
		); progn
	); if 
); foreach
(princ "\nmixLst: ") (print mixLst)
(princ "\n>>> Items in newLst (without errors): <<<")
(foreach x newLst (princ "\n")(print x))
(princ "\n*****************************************")
(if (and errCnt (/= errCnt 0)) (princ (strcat "\n " (itoa errCnt) " errors occured! ")))

(princ)
); defun

 

Using: (rtos itm), Result:

; mixLst:
; (10 "twenty" "thirty" 40 50 ("sixty") 70 "eighty" 90 ("one hundred"))
; >>> Items in newLst (without errors): <<<
; 90
; 70
; 50
; 40
; 10
; *****************************************
; 5 errors occured!

 

Using: (strcat itm), Result:

; mixLst:
; (10 "twenty" "thirty" 40 50 ("sixty") 70 "eighty" 90 ("one hundred"))
; >>> Items in newLst (without errors): <<<
; "eighty"
; "thirty"
; "twenty"
; *****************************************
; 7 errors occured!

 

Using: (/ itm 2.), Result:

; mixLst:
; (10 "twenty" "thirty" 40 50 ("sixty") 70 "eighty" 90 ("one hundred"))
; >>> Items in newLst (without errors): <<<
; 90
; 70
; 50
; 40
; 10
; *****************************************
; 5 errors occured!

 

Another test code I created after reading similar threads with vl-catch-***:

 

; try to offset an "INSERT/POINT" entity, to trigger an error?, or invoke unsupported method? (vla-offset)
; (vlax-invoke-method vla-obj "Offset" dist)
(defun C:test ( / d e o err-obj ) ; <- TESTED and WORKS ! (results are commented below)
(initget 1)
(if (setq d (getreal "\nInput offset distance: "))
	(while T
		(while (not (setq e (car (entsel "\nSelect object to offset: ")))) e)
		(setq o (vlax-ename->vla-object e))
		(if 
			(or
				(vl-catch-all-error-p (setq err-obj (vl-catch-all-apply 'vla-offset (list o d))))
				(vl-catch-all-error-p (setq err-obj (vl-catch-all-apply 'vlax-invoke (list o 'offset d))))
			)
			(progn ; caught an error
				(princ "\n** Object could not be offset **\n")
				(princ (vl-catch-all-error-message err-obj))
			)
		); if
	); while T
); if dist
(princ)
); defun

 

Results:

; Trying to perform an internal offset on a closed shape, using big offset value:
; ** Object could not be offset **
; Automation Error. Description was not provided.

; Trying to perform an offset on BLOCK/POINT object:
; ** Object could not be offset **
; ActiveX Server returned the error: unknown name: Offset

 

Another code (using loop with getstring):

; Everything being wrapped within a "while" loop:
(defun C:test ( / go layerNm layerObj errCnt );<- TESTED and WORKS!

(setq go T); set the loop flag to T

(while go ; here we wrap everything in a "while" loop, which exits, until a valid layername is provided.
	(setq LayerNm (getstring "\nInput layer's name to dump: "))
	(if LayerNm (setq go nil))
	
	
	(if
		(not 
			(vl-catch-all-error-p 
				(setq layerObj
					(vl-catch-all-apply 
						'vla-item 
						(list 
							(vla-get-Layers (vla-get-ActiveDocument (vlax-get-acad-object)))
							layerNm
						)
					)
				)
			)
		)
		(progn ; everything is OK
			(vlax-dump-object layerObj T)
			(textscr)
			(setq go nil) ; stop the loop
		); progn
		(progn ; caught an error
			(if (not errCnt) (setq errCnt 0))
			(setq errCnt (1+ errCnt))
			(princ "\n*** Layer not found! ***")
			(princ (strcat "\nNumber of attempts: " (itoa errCnt) " !"))
			(princ (strcat "\nThe error catched: \"" (vl-catch-all-error-message layerObj) "\" "))
			
			(setq go T) ; reset the loop flag to T
		); progn
	); if
); while go (end wrapping)

(princ)
); defun

 

Another (this time using lambda):

(defun C:test ( / o errCnt err-lst );<- TESTED and WORKS!
(vlax-for o (vla-get-Layers (vla-get-ActiveDocument (vlax-get-acad-object)))
	(if
		(vl-catch-all-error-p
			(vl-catch-all-apply
				'(lambda nil ; use (lambda) for multiple object manipulations within the error-trapper 
					(vla-put-Freeze o :vlax-false)
					(vla-put-Lock o :vlax-false)
					(vla-put-LayerOn o :vlax-true)
				)
			)
		)
		(progn ; caught an error
			(if (not errCnt) (setq errCnt 0))
			(setq errCnt (1+ errCnt))
			(setq err-lst (cons (vla-get-name o) err-lst))
		)
	)
); vlax-for
(if (and errCnt (/= errCnt 0))
	(progn
		(princ (strcat "\n " (itoa errCnt) " errors occured!"))
		(princ "\nThe following layers were not manipulated: ")
		(foreach x err-lst (princ "\n") (print x))
	)
)
(vlax-invoke (vla-get-ActiveDocument (vlax-get-acad-object)) 'Regen acActiveViewport) ; requires regen due changing the "layer on/off" property
(princ)
); defun

Results (printed in command prompt):

; Command: TEST
; 1 errors occured!
; The following layers were not manipulated:
; "VLD_AnnotateLINES" Regenerating model.

 

Now I think that lambda expression is used within vl-catch-all-apply, only when multiple manipulations must be performed (like the above code), and not just something like this:

(vl-catch-all-apply 'func (list arguments) )

Not sure If I'm entirely correct (but by now I got this opinion about the subject).

And I'm not sure why these vl-catch-*** functions are used, since I could achieve the same performance in the codes, without them. I've created this thread only to try to understand why and how they work and why people use these (a.k.a. errortrapers).

Mostly seen inside of foreach/vlax-for expressions, and maybe sometimes the vl-catch wrapping the foreach/vlax-for... can anyone elaborate in case I am correct?

 

 

 

The following codes also will not evaluate / reach the second line so the variable 'AcDocForB' will ALWAYS be nil

 

(or
	(setq AcDocForA (vla-get-ActiveDocument (vlax-get-acad-object))) 
	(setq AcDocForB (vla-get-ActiveDocument (vlax-get-acad-object))) 
)

I think there is a little misunderstanding, since you avoided reading the comments:

[color=#8b4513]; Start-End-UndoMark Testing:[/color]
[color=#8b4513]; pick a series of entities, to draw for each one its boundingbox[/color]
[color=#8b4513]; upon undoing [b][color=BLACK]([/color][/b]ctrl+Z[b][color=BLACK])[/color][/b], the Mark type [color=#2f4f4f]"A"[/color] should undo all the created BoundingBoxes[/color]
[color=#8b4513]; upon undoing [b][color=BLACK]([/color][/b]ctrl+Z[b][color=BLACK])[/color][/b], the Mark type [color=#2f4f4f]"B"[/color] should undo one by one, every created BoundingBox[/color]
[b][color=BLACK]([/color][/b]defun C:test [b][color=FUCHSIA]([/color][/b] / AcDocForA AcDocForB ent vla-obj ll ur p1 p2 p3 p4 [b][color=FUCHSIA])[/color][/b]
[b][color=FUCHSIA]([/color][/b]vl-load-com[b][color=FUCHSIA])[/color][/b] [b][color=FUCHSIA]([/color][/b]setvar 'errno 0[b][color=FUCHSIA])[/color][/b]
[b][color=FUCHSIA]([/color][/b]or
	[color=#8b4513]; [b][color=NAVY]([/color][/b]setq	AcDocForA [b][color=MAROON]([/color][/b]vla-get-ActiveDocument [b][color=GREEN]([/color][/b]vlax-get-acad-object[b][color=GREEN])[/color][/b][b][color=MAROON])[/color][/b][b][color=NAVY])[/color][/b] ; put semicolon here[/color]
	[b][color=NAVY]([/color][/b]setq	AcDocForB [b][color=MAROON]([/color][/b]vla-get-ActiveDocument [b][color=GREEN]([/color][/b]vlax-get-acad-object[b][color=GREEN])[/color][/b][b][color=MAROON])[/color][/b][b][color=NAVY])[/color][/b] [color=#8b4513]; or put semicolon here[/color]
[b][color=FUCHSIA])[/color][/b]

[b][color=FUCHSIA]([/color][/b]if AcDocForA [b][color=NAVY]([/color][/b]vla-StartUndoMark AcDocForA[b][color=NAVY])[/color][/b][b][color=FUCHSIA])[/color][/b][color=#8b4513]; Mark type: [color=#2f4f4f]"A"[/color][/color]

[b][color=FUCHSIA]([/color][/b]while T
	[b][color=NAVY]([/color][/b]while
		[b][color=MAROON]([/color][/b]not
			[b][color=GREEN]([/color][/b]and
				[b][color=BLUE]([/color][/b]setq ent [b][color=RED]([/color][/b]car [b][color=PURPLE]([/color][/b]entsel [color=#2f4f4f]"\Pick an entity to draw its BBox: "[/color][b][color=PURPLE])[/color][/b][b][color=RED])[/color][/b][b][color=BLUE])[/color][/b]
				[b][color=BLUE]([/color][/b]setq vla-obj [b][color=RED]([/color][/b]vlax-ename->vla-object ent[b][color=RED])[/color][/b][b][color=BLUE])[/color][/b]
			[b][color=GREEN])[/color][/b]
		[b][color=MAROON])[/color][/b]
		[b][color=MAROON]([/color][/b]if [b][color=GREEN]([/color][/b]or [b][color=BLUE]([/color][/b]member [b][color=RED]([/color][/b]getvar 'errno[b][color=RED])[/color][/b] '[b][color=RED]([/color][/b]7 52[b][color=RED])[/color][/b][b][color=BLUE])[/color][/b] [b][color=BLUE]([/color][/b]null ent[b][color=BLUE])[/color][/b][b][color=GREEN])[/color][/b] [b][color=GREEN]([/color][/b]princ [color=#2f4f4f]"\nYou missed, try again!"[/color][b][color=GREEN])[/color][/b][b][color=MAROON])[/color][/b]
	[b][color=NAVY])[/color][/b][color=#8b4513]; while[/color]
	
	[b][color=NAVY]([/color][/b]if AcDocForB [b][color=MAROON]([/color][/b]vla-StartUndoMark AcDocForB[b][color=MAROON])[/color][/b][b][color=NAVY])[/color][/b][color=#8b4513]; Mark type: [color=#2f4f4f]"B"[/color][/color]
	
	[b][color=NAVY]([/color][/b]vla-GetBoundingBox vla-obj 'll 'ur[b][color=NAVY])[/color][/b]
	[b][color=NAVY]([/color][/b]setq 
		p1 [b][color=MAROON]([/color][/b]vlax-safearray->list ll[b][color=MAROON])[/color][/b]
		p2 [b][color=MAROON]([/color][/b]vlax-safearray->list ur[b][color=MAROON])[/color][/b]
		p3 [b][color=MAROON]([/color][/b]list [b][color=GREEN]([/color][/b]car p2[b][color=GREEN])[/color][/b] [b][color=GREEN]([/color][/b]cadr p1[b][color=GREEN])[/color][/b][b][color=MAROON])[/color][/b] [color=#8b4513]; lr[/color]
		p4 [b][color=MAROON]([/color][/b]list [b][color=GREEN]([/color][/b]car p1[b][color=GREEN])[/color][/b] [b][color=GREEN]([/color][/b]cadr p2[b][color=GREEN])[/color][/b][b][color=MAROON])[/color][/b] [color=#8b4513]; ul[/color]
	[b][color=NAVY])[/color][/b]
	[b][color=NAVY]([/color][/b]LWPoly-Red [b][color=MAROON]([/color][/b]list p1 p3 p2 p4[b][color=MAROON])[/color][/b] 1[b][color=NAVY])[/color][/b]
	
	[b][color=NAVY]([/color][/b]if AcDocForB [b][color=MAROON]([/color][/b]vla-EndUndoMark AcDocForB[b][color=MAROON])[/color][/b][b][color=NAVY])[/color][/b][color=#8b4513]; Mark type: [color=#2f4f4f]"B"[/color][/color]
[b][color=FUCHSIA])[/color][/b][color=#8b4513]; while T[/color]

[b][color=FUCHSIA]([/color][/b]if AcDocForA [b][color=NAVY]([/color][/b]vla-EndUndoMark AcDocForA[b][color=NAVY])[/color][/b][b][color=FUCHSIA])[/color][/b][color=#8b4513]; Mark type: [color=#2f4f4f]"A"[/color][/color]
[b][color=FUCHSIA]([/color][/b]princ[b][color=FUCHSIA])[/color][/b]
[b][color=BLACK])[/color][/b][color=#8b4513]; defun[/color]

[b][color=BLACK]([/color][/b]defun LWPoly-Red [b][color=FUCHSIA]([/color][/b]lst cls[b][color=FUCHSIA])[/color][/b]
[b][color=FUCHSIA]([/color][/b]entmakex 
	[b][color=NAVY]([/color][/b]append 
		[b][color=MAROON]([/color][/b]list 
			[b][color=GREEN]([/color][/b]cons 0 [color=#2f4f4f]"LWPOLYLINE"[/color][b][color=GREEN])[/color][/b]
			[b][color=GREEN]([/color][/b]cons 100 [color=#2f4f4f]"AcDbEntity"[/color][b][color=GREEN])[/color][/b]
			[b][color=GREEN]([/color][/b]cons 100 [color=#2f4f4f]"AcDbPolyline"[/color][b][color=GREEN])[/color][/b]
			[b][color=GREEN]([/color][/b]cons 62 1[b][color=GREEN])[/color][/b]
			[b][color=GREEN]([/color][/b]cons 90 [b][color=BLUE]([/color][/b]length lst[b][color=BLUE])[/color][/b][b][color=GREEN])[/color][/b]
			[b][color=GREEN]([/color][/b]cons 70 cls[b][color=GREEN])[/color][/b]
		[b][color=MAROON])[/color][/b]
		[b][color=MAROON]([/color][/b]mapcar [b][color=GREEN]([/color][/b]function [b][color=BLUE]([/color][/b]lambda [b][color=RED]([/color][/b]p[b][color=RED])[/color][/b] [b][color=RED]([/color][/b]cons 10 p[b][color=RED])[/color][/b][b][color=BLUE])[/color][/b][b][color=GREEN])[/color][/b] lst[b][color=MAROON])[/color][/b]
	[b][color=NAVY])[/color][/b]
[b][color=FUCHSIA])[/color][/b]
[b][color=BLACK])[/color][/b]

This code is actually 2 in 1: (instead of posting 2 separate codes, I did only one where a semicolon must be put infront of one of the following rows you commented.

The or subr has no practical usage in the code (I just do it for an easier revision - later if needed) without getting any errors in the code (I usually wrap parts of the code within or, so it would mean that there are several options that might work).

The alternative would be commenting behind each row/block of the code by typing "or this can work aswell / or this is another option", but I find it more readable using the actual or function.

Sorry for the confusion - I have these weird habbits, which doesn't make sence for you (including the (while T... part from the code).

By the way I tested my end/undo mark attempt, and changed the position of

(if AcDocForB (vla-StartUndoMark AcDocForB)); Mark type: "B"

so now the undo'ing is performing correctly.

Thanks alot for your help! :) and sorry for the big-ass reply, I went too intrigued/curious.

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