Jump to content

Block Find


Glen Smith

Recommended Posts

Does anyone have a LISP or VBA script that will take input from a text file listing the block handles of multiple blocks and zoom in on the block, allow me to perform some function (EATTEDIT) on that block and move to the next in the list?

 

I have blocks that show doors with a room number attribute. New doors got added without updating the room number. So I can export the attributes and get a list of the doors, (and other blocks) sort it in excel, delete the doors that don't need work and save it. I can't update the door number attribute in the excel file and import, since I don't know where it is. I have not had any luck with the find command, it would appear that it does not search attributes.

 

I'm guessing that this is not a complex programing task, and would be a good one to learn on, but naturally, this drawing needs to be updated yesterday so the PM's can work on costing the change orders.

 

Thanks.

 

Glen

Link to comment
Share on other sites

Find will search for a value in an attribute. Say you have a block with an attribute tag of wire# and you have wire numbers that are LP1-HA, LP1-HB, and LP1-HC you can find and replace the values as you need.

Link to comment
Share on other sites

Does anyone have a LISP or VBA script that will take input from a text file listing the block handles of multiple blocks and zoom in on the block, allow me to perform some function (EATTEDIT) on that block and move to the next in the list?

 

I have blocks that show doors with a room number attribute. New doors got added without updating the room number. So I can export the attributes and get a list of the doors, (and other blocks) sort it in excel, delete the doors that don't need work and save it. I can't update the door number attribute in the excel file and import, since I don't know where it is. I have not had any luck with the find command, it would appear that it does not search attributes.

 

I'm guessing that this is not a complex programing task, and would be a good one to learn on, but naturally, this drawing needs to be updated yesterday so the PM's can work on costing the change orders.

 

Thanks.

 

Glen

 

Not sure if this is something you may want to try.

 

Under Express Tools > Blocks - Export Attribute Information

This take all of the blocks attributes as well as block name and handle information and places it in a text file. You can copy the text file and place it in Excel for editing. When done just copy the spread sheet and paste it overwriting the previous information in the text file.

Then under Express Tool > Blocks - Import Attribute Information

and the blocks will be automatically updated.

Link to comment
Share on other sites

Find will search for a value in an attribute. Say you have a block with an attribute tag of wire# and you have wire numbers that are LP1-HA, LP1-HB, and LP1-HC you can find and replace the values as you need.

 

I though that Find should look in the attributes but the quick test I did before packing it in for the day didn't seem to work. I had three cameras with the CAMERA_NUM attribute set to "C#" I wanted to find the little ******s and set them to the new value. I did a find and put C# in the field and got 0 hits.

 

So I set the attribute to something like"HI GLEN THIS IS A LONG ATTRIBUTE VALUE SO MAYBE YOU CAN FIND THIS" and imported it using import attributes (as The Buzzard has suggested above.)

 

Then I scanned the drawing looking for cameras with ridiculously long attributes streaming from them.

 

I had intended to use the export attributes function to find the blocks with missing and or duplicate attributes, retain only the ones I want to work with and then saving. Since the txt/Excel file has the block handle, I know AutoCAD can find them, I just don't know how to make it do so.

 

I'll look at some of the LISP routines that do similar things and see if I can get something usefull.

 

Thanks.

Glen

Link to comment
Share on other sites

Try this Glen:

 

(defun c:zmblk (/ file nl lst Minp Maxp)
 (vl-load-com)
 (if (setq file (getfiled "Select Text File" "" "txt" )
   (progn
     (setq file (open file "r"))
     (while (setq nl (read-line file))
       (setq lst (cons nl lst)))
     (close file)
     (foreach Obj (mapcar 'vlax-ename->vla-object
                    (vl-remove-if 'null
                      (mapcar 'handent (reverse lst))))
       (vla-getBoundingBox Obj 'Minp 'Maxp)
       (vla-ZoomWindow
         (vlax-get-acad-object) Minp Maxp)
       (command "_.eattedit"
         (vlax-vla-object->ename Obj))))
   (princ "\n<< No File Selected >>"))
 (princ))

Link to comment
Share on other sites

OK I'm making progress. It took me a while to discover that I had to delete the leading single quote that is in the attributes txt file. Now it zooms to each block to let me work on it, but I'm zoomed in too far, I can't see enough of the drawing around the block to figure out what room number I'm in. Is there a way for me to set the level of zoom rather than windowing on the block?

 

I took the liberty of verbosing the code and slightly reformating so I could get a better idea of what was going on:

 

(defun c:zmblk (/ file nl lst Minp Maxp)
  (vl-load-com)
  (if (setq file (getfiled "Select Text File" "" "txt" )
     (progn
        (setq file (open file "r"))
(princ "\n<< file open >>")
        (while (setq nl (read-line file))
           (setq lst (cons nl lst))
(princ "\n<< reading lines >>")
        )
        (close file)
        (princ "\n<< file closed >>")
        (foreach Obj (mapcar 'vlax-ename->vla-object
                    (vl-remove-if 'null
                    (mapcar 'handent (reverse lst))))
           (princ "\n<< with each object do something>>")
           (vla-getBoundingBox Obj 'Minp 'Maxp)
           (princ "\n<< got bounding box >>")
           (vla-ZoomWindow
                    (vlax-get-acad-object) Minp Maxp)
           (princ "\n<< zoomwindow >>")
           (command "_.eattedit"
                (vlax-vla-object->ename Obj)
           )
        (princ "\n<< done with all objects >>")
        )
     (princ "\n<< exiting progn wrap >>")
     )
  (princ "\n<< No File Selected >>"))
(princ "\n<< exiting if statement >>")
  (princ)
(princ "\n<< done with function >>")
)

Link to comment
Share on other sites

WHHEEEE!

 

With a search here on the boards and a surf through the VLISP help file, I found the ZoomCenter command. I made the following change to the

;            (vla-ZoomWindow (vlax-get-acad-object) Minp Maxp)
           (vla-ZoomCenter (vlax-get-acad-object) Minp 400)

and am now using this code to make my changes.

 

Thanks to all. Once I can show the boss that I'm working and not playing with code, I'll try to get the magnification so I can set it rather than hard code it so I can use this with different scale drawings.

 

Glen

Link to comment
Share on other sites

I thought I had it working.

 

I created a new selection set and now can't make it work. I thought that the input file was just the block name (number) without the leading quote. But using the same method again to produce the set does not work.

 

Since I was done with the set I used successfully, I wrote the new one over it, and can't compare the two.

 

I've included one of the selection sets with slightly different attempts of formating the data, can anyone tell me what I'm doing wrong?

 

Glen

DURRES ALARM.txt

Link to comment
Share on other sites

This is a better way to do the zoom:

 

(defun c:zmblk (/ file nl lst Minp Maxp pts elst)
 (vl-load-com)
 (if (setq file
       (getfiled "Select Text File"
         (if *load *load "") "txt" )
   (progn
     (setq *load file file (open file "r"))
     (while (setq nl (read-line file))
       (setq lst (cons nl lst)))
     (close file)
     (if (setq elst (vl-remove-if 'null
                      (mapcar 'handent (reverse lst))))
       (foreach Obj (mapcar 'vlax-ename->vla-object elst)                     
         (vla-getBoundingBox Obj 'Minp 'Maxp)
         (setq pts (mapcar 'vlax-safearray->list (list Minp Maxp)))
         (vla-ZoomCenter
           (vlax-get-acad-object)
             (vlax-3D-point
               (polar (car pts)
                      (apply 'angle pts)
                      (/ (apply 'distance pts) 2.)))
           400.)
         (command "_.eattedit"
           (vlax-vla-object->ename Obj)))))
   (princ "\n<< No File Selected >>"))
 (princ))

 

I can manipulate the code to ignore your leading apostrophe if you like :)

Link to comment
Share on other sites

Lee, that would be great, I don't understand why it worked (perfectly by the way) one time. I went through and fixed a bunch of things, then exported a different set of attributes and I have not been able to use it again.

 

I assume that you would pull the line in as a string and kill the first charecter? If so, can it just read to the first space, then dump the rest of the line? That way it could read the attribute export files (the txt versions anyway) without any modification of the txt file.

 

Thanks again.

I promise to keep staring at the code and looking stuff up till I understand it!

 

Glen

Link to comment
Share on other sites

Yes, currently, this assumes that you just have a handle on each line of the file - and nothing else on the line.

 

But i can manipulate the code to just collect the line up to the first space/other delimiter, and also strip the first character. :)

Link to comment
Share on other sites

Try this Glen, it assumes a TAB between items - as shown in your attached txt file.

 

(defun c:zmblk (/ file nl lst Minp Maxp pts elst)
 (vl-load-com)
 (if (setq file
       (getfiled "Select Text File"
         (if *load *load "") "txt" )
   (progn
     (setq *load file file (open file "r"))
     (while (setq nl (read-line file))
       (setq lst (cons (car (StrBrk nl 9)) lst)))
     (close file)
     (if (setq elst (vl-remove-if 'null
                      (mapcar 'handent
                        (mapcar
                          (function
                            (lambda (x)
                              (substr x 2))) (reverse lst)))))
       (foreach Obj (mapcar 'vlax-ename->vla-object elst)                     
         (vla-getBoundingBox Obj 'Minp 'Maxp)
         (setq pts (mapcar 'vlax-safearray->list (list Minp Maxp)))
         (vla-ZoomCenter
           (vlax-get-acad-object)
             (vlax-3D-point
               (polar (car pts)
                      (apply 'angle pts)
                      (/ (apply 'distance pts) 2.)))
           400.)
         (command "_.eattedit"
           (vlax-vla-object->ename Obj)))))
   (princ "\n<< No File Selected >>"))
 (princ))

(defun StrBrk (str chrc / pos lst)
 (while (setq pos (vl-string-position chrc str))
   (setq lst (cons (substr str 1 pos) lst)
         str (substr str (+ pos 2))))
 (reverse (cons str lst)))

Link to comment
Share on other sites

I tried loading it and AutoCAD sez

Command: _appload zmblk.lsp successfully loaded.

Command: ; error: malformed list on input

 

 

I tried loading it in the VLISP editor and having it format the code - it says there's a missing right paren. I see why someones sig says LISP = Lost In Superfluous Parenthesis!

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