Inserting blocks from file to coords of COGO points by layer - LISP problems

Inserting blocks from file to coords of COGO points by layer - LISP problems

DeliD
Participant Participant
869 Views
5 Replies
Message 1 of 6

Inserting blocks from file to coords of COGO points by layer - LISP problems

DeliD
Participant
Participant

Dear Members!

 

I wrote a LISP to insert specified blocks to coords of COGO points with specified layers (it's not a working way to change the point style or label, sometimes I need to move the block separately from the point, or freeze the point but not the block). It works nice, but there are some problems I encountered when I tried to "improve" the code:

 

- it places the blocks without problem, but if I select more than 1 COGO point, it writes an error in the command line after inserting the last block:
"bad argument type: lselsetp #<VLA-OBJECT IAcadSelectionSet 000000005cc085d8>"

I looked it up, and it means the selection set is empty, but I don't understand what does it really mean. Any way to get rid of this error message?

 

- I tried to make it write the total number of inserted blocks in the command line after inserting the last block, but I only get the "lselsetp" error (but with different numbers at the end of it).

One of the methods I tried:

(setq blks (ssget "X" '((0 . "INSERT")))
	 blkcount (sslength blks))
(princ blkcount)

 

- my company have 576 layers that have a specified block to insert, so I copied the "(if (= player "...")..." section 576 times. Is there any way to make it simpler?

 

- my company uses a lot of blocks stored in a seperate DWG. Is there a way of selecting and inserting only the needed blocks from it? Currently the LISP copies and inserts all of the block definitions into the actual drawing and it takes time (and makes the size of the file unnecessarily large).

 

- is there a way to make it check if there is already a block on a selected COGO point? Maybe display the "Do you want to replace existing blocks?" question in the command line after starting the command with the options "Yes/No"?

 

 

My code:

;====DISPLAY ERROR
(defun *error* ( msg )
        (if (not (member msg '("Function cancelled" "quit / exit abort")))
            (princ (strcat "\nError: " msg))
        )
        (princ)
    )


;====PROGRAM
(defun c:bf1 (/ pnts i pnt1 x pnt eastng northng elev player blks blkcount)
  (vl-load-com)
	(setq oldsnap (getvar "osmode") ;saves the old settings
	      oldblipmode (getvar "blipmode")
	      oldlayer (getvar "CLAYER"))
	(setvar "osmode" 0) ;turn off all objact snap
	(setvar "blipmode" 0)
	(command "_.insert" "blocks.dwg")(command) ;insert drawing with all the block definition, drawing must be in ACAD support path!
	
	(if (setq pnts (ssget '((0 . "AECC_COGO_POINT")))) ;select COGO points
	(progn
	(setq i 0)
	(repeat (sslength pnts) ;repeating to all selected COGO points
		setq pnt1 (vlax-ename->vla-object (ssname pnts i))
		(progn
        (vlax-for x
           (setq pnts (vla-get-activeselectionset (vla-get-activedocument (vlax-get-acad-object))))
           (setq pnt (vlax-get x 'number)
              eastng (vlax-get x 'easting)
              northng (vlax-get x 'northing)
			  elev (vlax-get x 'elevation)
              pfolia (vlax-get x 'layer)
           ) ;end of setq
		(if (= player "Layer1")
				(command
				"_.-layer" "_set" "Layer_Block_1" ""
				"_.insert" "Block1" (list eastng northng elev) "" "" ""
				)
			   )
		(if (= player "Layer2")
				(command
				"_.-layer" "_set" "Layer_Block_2" ""
				"_.insert" "Block2" (list eastng northng elev) "" "" ""
				)
			   )
(setq i (1+ i))
) ;end of vlax-for
) ;end of progn in repeat
) ;end of repeat
) ;end of progn in if
(princ "No point selected!")
) ;end of if
(setvar "osmode" oldsnap) ;restore old settings
(setvar "blipmode" oldblipmode)
(setvar "CLAYER" oldlayer)
(princ)
) ;end of defun



I hope you can help me with these, I'd be very happy 🙂

Thanks for considering my request.

 

Daniel

 

 

 

 

0 Likes
Accepted solutions (1)
870 Views
5 Replies
Replies (5)
Message 2 of 6

ВeekeeCZ
Consultant
Consultant
Accepted solution

Welcome to the forums!

 

You should decide whether you want to use one type of loap or another. One should be enough.

 

BTW the C3D stuff you should rather post HERE

And usually some sample dwg file to test is helpful.

 


@DeliD wrote:

...

My code:

...
	(command "_.insert" "blocks.dwg")(command) ;insert drawing with all the block definition, drawing must be in ACAD support path!
	
	(if (setq pnts (ssget '((0 . "AECC_COGO_POINT")))) ;select COGO points
	(setq i 0)
	(repeat (sslength pnts) ;repeating to all selected COGO points
		setq pnt1 (vlax-ename->vla-object (ssname pnts i))
		(progn
        (vlax-for x
           (setq pnts (vla-get-activeselectionset (vla-get-activedocument (vlax-get-acad-object))))
           (setq pnt (vlax-get x 'number)
              eastng (vlax-get x 'easting)
              northng (vlax-get x 'northing)
			  elev (vlax-get x 'elevation)
              pfolia (vlax-get x 'layer)
           ) ;end of setq
		(if (= player "Layer1")
				(command
				"_.-layer" "_set" "Layer_Block_1" ""
				"_.insert" "Block1" (list eastng northng elev) "" "" ""
				)
			   )
		(if (= player "Layer2")
				(command
				"_.-layer" "_set" "Layer_Block_2" ""
				"_.insert" "Block2" (list eastng northng elev) "" "" ""
				)
			   )
...

 

0 Likes
Message 3 of 6

CodeDing
Advisor
Advisor

@DeliD ,

 

This line leads me to believe you might be using Civil 3D?

(if (setq pnts (ssget '((0 . "AECC_COGO_POINT")))) ;select COGO points

If that is the case, you can utilize point groups and point/label styles to better manage inserting blocks at cogo point locations. Are you using Civil 3D?

 

Best,

~DD

 

0 Likes
Message 4 of 6

DeliD
Participant
Participant

Thanks, I didn't know it's both for loop. I started to learn LISP 1 week ago and I don't really understand these "vla-things" 🙂 I deleted the "repeat" part and kept the "vlax-for", and now there is no error message after selecting more than 1 COGO.

I will make the sample DWG you mentioned and move this thread to the C3D board.

Message 5 of 6

DeliD
Participant
Participant

Yes, I use C3D. Thanks for the advice but let me quote myself:
"I wrote a LISP to insert specified blocks to coords of COGO points with specified layers (it's not a working way to change the point style or label, sometimes I need to move the block separately from the point, or freeze the point but not the block)"

0 Likes
Message 6 of 6

ВeekeeCZ
Consultant
Consultant

@DeliD wrote:

... I started to learn LISP 1 week ago and I don't really understand these "vla-things" 🙂 I deleted the "repeat" part and kept the "vlax-for"...


 

Well, that was probably the best thing to do. 

But since you're new I've decided to fix your 'repeat' part. There is a number of errors... 

(if (setq pnts (ssget '((0 . "AECC_COGO_POINT"))))
  (progn 	; wrap all 'then' stuff
    (setq i 0)
    (repeat (sslength pnts)
      (setq obj (vlax-ename->vla-object (ssname pnts i))) 	; missing parenthesis
      ;(progn  - useless

      (setq pnt (vlax-get obj 'number)
            eastng (vlax-get obj 'easting)
            northng (vlax-get obj 'northing)
            )
      ;...
      (setq i (1+ i))
      ) ; repeat
    ) ; progn
  )

This is the incremental method, which might look more understandable, but there are quite a lot to things that you need to think about to be correct. And don't forget to actually increment the index in the end.

 

But I would recommend using the 'reverse' method. It requires fewer expressions and all of them are done at the beginning of the loop, so it's less prone to errors:

(if (setq pnts (ssget '((0 . "AECC_COGO_POINT"))))
  (repeat (setq i (sslength pnts))
    (setq obj (vlax-ename->vla-object (ssname pnts (setq i (1- i)))))

    (setq pnt (vlax-get obj 'number)
          eastng (vlax-get obj 'easting)
          northng (vlax-get obj 'northing)
          )
      ;...
    ) ; repeat
  )

Also, look HERE for other methods.

0 Likes