Using refedit to edit nested block through Autolisp in AutoCAD 2020

ShricharanaB
Advocate
Advocate

Using refedit to edit nested block through Autolisp in AutoCAD 2020

ShricharanaB
Advocate
Advocate

Hi,

This is my first question in this forum so please bear with me.

I'm a beginner in Autolisp and donot have a good handle on all the concepts yet. 

I'm trying to create a lisp routine for my company where I need to run a function on the block before the refedit editor opens. I can currently get it to work for the main block (See attached PartialWorkingMethod.lsp ). However it does not open the nested block to edit in place like the refedit command does.

 

I'm trying two methods to get it to work on nested blocks. Some ideas and/or code snippets found in various question other people have asked.

Method 1 (See attached  Method_1.lsp )

          Here I'm using nentsel to get the depth of the nested block in the main block and setting the main block as selected object by sending the main block entity name to ssadd and then using sssetfirst  and then calling _.-refedit. Since I am setting the main block as selected it won't select any nested block for edit looping to the correct nested block with the command "N" . I tried to send the nested block name to ssadd but that returns nill. Anything I can use here to set the nested block as the selected so that the refedit can loop to the correct nested block with the command "N" ?  Or a way to send it directly to the refedit command? 

 

Method 2 (See attached  Method_2.lsp )

         Here I'm calling the refedit command first and then pausing for input. After the selection I'm trying to get the selection set from the active document and iterating for the first object. I'm missing something here because the object selected after calling refedit is not added to the selection set, so it refers to an older selection set I think.

 

Any insight on what I'm doing wrong or what I can use to get it working? 

A completely new way of doing it will be fine as well. Any help is greatly appreciated. Thanks in advance. 

 

Edit 1: The default refedit selects the nested block when the refedit window is open

ShricharanaB_0-1664526534948.png

But my routine selects the main block. 

ShricharanaB_1-1664526671165.png

 

As the users will have blocks with a lot of nested block they will have to iterate their nested block selection manually before they enter the nested block to edit. I need it to select the nested block that is being clocked on when this routine is run.

 

And (command "_.-refedit" "N") just opens the main block for editing not the nested block. 

 

The final goal is to check the presence of a particular attribute in the selected main block and continue with the refedit if it in NOT present. If it is present then quit with a message.

I have figured out how to extract the attributes and values list. But not the refedit part.

 

 

0 Likes
Reply
Accepted solutions (1)
1,556 Views
13 Replies
Replies (13)

ВeekeeCZ
Consultant
Consultant

Post some sample drawing and better describe your goal. (video?)

I've tried your Partly working routine and seems to work fine even on nested blocks.

ShricharanaB
Advocate
Advocate

Hi, A thousand thanks for checking the code. 

I have updated the main question to reflect the final goal and tried to better explain the issue.

 

The partly working routine opens the main block for editing not the nested one for me. 

0 Likes

ShricharanaB
Advocate
Advocate

Attaching a sample drawing as max number is reached in the main post. 

0 Likes

ВeekeeCZ
Consultant
Consultant
Accepted solution

Try this?

 

(defun c:refedit+ ( / s e)

  (if (and (setq s (entsel))
	   (setq e (car s))
	   (= "INSERT" (cdr (assoc 0 (entget e))))
	   (progn
;;;	     (or (and (= "MyBlock" (getpropertyvalue e "BlockTableRecord/Name")) ; blockname check
;;;		      (= "0" (getpropertyvalue e "Tagname"))			 ; tagvalue check
;;;		      (domything))
;;;		 )
	     T)
	   )
    (command-s "_.refedit" (cadr s)))
  (princ)
  )

ShricharanaB
Advocate
Advocate
Your code works great!.
But I need to get attributes from the nested block as well and cannot show the reference selection window.
I need to use "_.-refedit" instead of "_.refedit" for that right right?
I'm trying to modify the code for that.
I had no idea the second element in the nentsel and entsel were always selection points and could send them to refedit. Thank you for that insight!!!
I'll let you know once I get it working properly.
0 Likes

ВeekeeCZ
Consultant
Consultant

@ShricharanaB wrote:
...But I need to get attributes from the nested block > use (nentselp) if necessary
as well and cannot show the reference selection window.  > no idea what you mean
I need to use "_.-refedit" instead of "_.refedit" for that right right? > dunno why that would be, probably not
I'm trying to modify the code for that.... > good.

Kent1Cooper
Consultant
Consultant

@ShricharanaB wrote:
....
But I need to get attributes from the nested block as well and cannot show the reference selection window.
I need to use "_.-refedit" instead of "_.refedit" for that right right?
.....

Yes.  In most cases, running a command inside an AutoLisp (command) function always uses the command-line version and not the dialog-box version, without needing to include the hyphen that you would need to avoid the dialog box if doing it manually.  But in the case of REFEDIT, without the hyphen, even inside a (command) function, you still get the dialog box for selection of the Block level to work on.  With the hyphen, you get the command-line prompt, which you will need to experiment with to determine the answers to give it to get the right nested Block.

Kent Cooper, AIA

ShricharanaB
Advocate
Advocate
@ВeekeeCZ  Thanks a lot for moving me forward in this. I was stuck for two days. 

@Kent1Cooper  Thank you for clear explanation. 

 

I have attached the fully working file. Though I think it can be coded better. Could you point me in the right direction so that I can improve this code? and any code I write in the future of course!

0 Likes

ВeekeeCZ
Consultant
Consultant

Just a few notes.

* I did not think of (nentselp) without any argument, point specifically. Never used it. It seems that (nentsel) could be just fine for your case.

* the question is, whether this pre-programmed restriction isn't too tight for the users. Possibly you can allow to switch to the dialog version by (nentsel "Select nested entity or use [Dialog]: ")

* not sure about dynamic blocks - doesn't it destroy all the dyn parameters? I would tend to exclude them from the editing.

* perhaps, instead of testing dyn blocks, simple (if (> (getvar 'cmdactive) 0) (command "_A" "_Y")) would solve the issue too.

* the (cond) function does not need (progn) to wrap "result" expressions

* definitely add the *error* function to reset the CMDECHO.

* localize your variables 

* there is (1- x) function available for (- x 1). (1+) too.

* not sure about (sssetfirst nil nil) why that is needed.

 

0 Likes

ShricharanaB
Advocate
Advocate

 

Hi,

First of all, thanks for going through the code.  Really appreciate it.

 

Just a few notes.

* I did not think of (nentselp) without any argument, point specifically. Never used it. It seems that (nentsel) could be just fine for your case. > I checked the code again and yes, it seems nentsel and nentselp does not make any difference in my case. 

* the question is, whether this pre-programmed restriction isn't too tight for the users. Possibly you can allow to switch to the dialog version by (nentsel "Select nested entity or use [Dialog]: ") > The goal is to prevent users from editing certain blocks. If the dialogue box for bedit opens then they could choose the block we don't want edited and open it for editing.

* not sure about dynamic blocks - doesn't it destroy all the dyn parameters? I would tend to exclude them from the editing. > Yes, refedit would destroy all the dyn params. I will have to think on that a little or will have to ask our users if they need the ability to refedit dynamic blocks.

* perhaps, instead of testing dyn blocks, simple (if (> (getvar 'cmdactive) 0) (command "_A" "_Y")) would solve the issue too. > Not sure which part of the code you are referring to.

* the (cond) function does not need (progn) to wrap "result" expressions > This I think happened when I switched form IF condition. Previously I had issues with IF condition evaluating the expressions in reverse when (progn) was not used.

* definitely add the *error* function to reset the CMDECHO. > Not sure how to implement that. Could you point me to an example?

* localize your variables  > Aren't all the variables defined inside a defun local to that defun? Or am I  misinterpreting what you are saying?

* there is (1- x) function available for (- x 1). (1+) too. > Right! I was experimenting with the reduction value (by 0, 1 ,2 ) and settled on 1. Forgot to change it to (1- x)  format. Fixed.

* not sure about (sssetfirst nil nil) why that is needed. > When I select the entity before calling the editref command it would not process it correctly and would throw up keyword error. So I'm deselecting everything before it calls for nentselp. Not sure why its happening though. May be an active selection set interferes with the refedit command since we send it a point of selection and another selection already exists?

0 Likes

ShricharanaB
Advocate
Advocate
Just went through "Localising Variables" by Lee Mac. I understand what you are saying. Will localize the variables. I thought they were just a way to show the variables used in a function till now since I assumed any variable used in a defun was automatically localized (as is the case in C++).
0 Likes

ВeekeeCZ
Consultant
Consultant

So Lee has a good article about error handling too, HERE 

0 Likes

ShricharanaB
Advocate
Advocate

Looks like I have to go through that entire tutorial section once . 

Thank you.  I went through the error handling tutorial and was able to implement it in my code.

0 Likes