Jump to content

Use Lisp to search & insert multiple drawings as blocks.


rob150588

Recommended Posts

Morning all.

 

I'v written a very short routine to insert map tiles we have on our server where all the user has to do is type in the Grid reference they require. All the tiles are named by their reference (i.e. SJ4522 or NZ0572)

 

 
(defun c:mmbmap ( / GRDREF MAPPATH)
 (setvar "cmdecho" 1)
 (setq GRDREF (getstring "Enter Grid Ref [sO4522]: "))
 (setq MAPPATH (strcat "N:/CAD/2D/MappingTiles/" GRDREF ".dwg"))
 (command "_.insert" MAPPATH "0,0,0" "1" "" "")
 (command "zoom" "o" "l" "")
 (princ))

 

This is all very straightforward, BUT (there's always a but), about 10% of the tiles are so large in file size, they are split into 4 tiles (i.e. instead of SE5076, it would be; SE5076NE, SE5076NW, SE5076SE, SE5076SW).

 

So what I'm asking is whether the routine I have can be modified to search for just the first 6 characters of the filename, and if it finds multiple files with that name to insert all of them ?

Link to comment
Share on other sites

I would recommend looking to the dos_find function. It is a part of the DosLib which can be downloaded for free at http://www.mcneel.com

 

You are able to do a wild card search for files and it will return a list of file names. Then knowing the number of items in the list do a repeat on the insert part of your routine. Plus DosLib has many other useful functions made available.

 

regards and happy coding!

 

Hippe013

Link to comment
Share on other sites

Thanks for your reply Hippe013.

 

That potentially looks like it could do the job...

 

Would I be right in assuming that DosLib would then have to be installed on each computer that would need to call the function ?

 

Or is it possible to put the required function on a server and have it called from there ?

 

I would prefer the latter option as this is an enterprise customisation to be used in severall locations with lots of machines.

 

Cheers.

Link to comment
Share on other sites

Actually if you put your Drawings in Autocad reference folder as shown below , you could give the chance to functions to find any one

of them you want. :)

 

Add the drawings to this folder to let the routine find them for you ....

"C:\\Program Files\\AutoCAD 2009\\support\\YourDrawingName.dwg"
Hope this routine would help you with it .

(defun c:Test ( / Nme FName) (vl-load-com)
 (if (and (setq Nme (getstring T "\n Enter name of Drawing :" ))
     (setq FName (findfile (strcat Nme ".dwg")))
          )
 (vl-cmdf "_.-insert" FName pause "" "" "")
   (alert "File not found ")
   )
 (princ)
)

Tharwat

Link to comment
Share on other sites

Thanks for your reply Hippe013.

 

That potentially looks like it could do the job...

 

Would I be right in assuming that DosLib would then have to be installed on each computer that would need to call the function ?

 

Or is it possible to put the required function on a server and have it called from there ?

 

I would prefer the latter option as this is an enterprise customisation to be used in severall locations with lots of machines.

 

Cheers.

 

DosLib is an arx file and would simply need to be added to each computer's startup suite found in appload. The actual arx file would reside somewhere on the server.

Link to comment
Share on other sites

Here's one I did a year or so ago for quickly bringing in GIS DWGs. It just inserts a selected group of DWG/DXFs at 0,0,0.

 

(defun c:GISIn (/ lst)
 ;; Alan J. Thompson
 (if (setq lst (dos_getfilem
                 "Select drawing files to insert at 0,0,0"
                 (getvar "dwgprefix")
                 "*.dwg;*.dxf|*.DXF;*.DWG"
               )
     )
   (foreach x (cdr lst) (vl-cmdf "_.-insert" (strcat (car lst) x) "0,0,0" "" "" ""))
 )
 (princ)
)

 

 

 

All you have to do is put the arx file on the server and load it from your company acaddoc file.

 

Here's what I keep in our acaddoc.LSP:

 

(vl-some
 (function (lambda (dos)
             (or (vl-position dos (arx))
                 (not (vl-catch-all-error-p (vl-catch-all-apply (function arxload) (list dos))))
             )
           )
 )
 '("doslib17.arx" "doslib18.arx")
)

 

Could be shortened, but I need it to load for 2009 and 2011.

Link to comment
Share on other sites

From my acad.lsp:

(defun load_exp (/ v p a av)
 (setq v (ver)
       p (getvar "PLATFORM")
       a (getvar "ACADVER"))

 (setq av (cond ((and (wcmatch a "*12*")
                      (wcmatch p "*DOS*"))
                  "12DOS")
                ((and (wcmatch a "*12*")
                      (wcmatch p "*Win*"))
                  "12WIN")
                ((and (wcmatch a "*13*")
                      (wcmatch p "*DOS*"))
                  "13DOS")
                ((and (wcmatch a "*13*")
                      (wcmatch p "*Win*"))
                  "13WIN")
                ((wcmatch a "*14*")
                  "14")
                ((wcmatch a "*15*")
                  "15")
                (T "UnKnown")))

 (cond ((= av "12DOS")
        (and (not (member "C:/ACAD/12/ACADAPP.EXP" (ads)))
             (xload "c:/acad/12/acadapp.exp"))
        (and (not (member "C:/ACAD/12/HPMPLOT.EXP" (ads)))
             (xload "c:/acad/12/hpmplot.exp"))
        (and (not (member "C:\\ACAD\\UT\\DOSLIB12.EXP" (ads)))
             (xload "doslib12.exp")))
       ((= av "12WIN")
        (and (/= (type dos_dir) 'EXSUBR)
             (xload "doslib12.exe")))
       ((= av "13DOS")
        (xload "c:/acad/13/acadapp.exp")
        (xload "c:/acad/13/hpmplot.exp")
        (and (/= (type dos_dir) 'EXSUBR)
             (xload "doslib13.exp")))
       ((= av "13WIN")
        (load "c:/acad/common/ai_utils.lsp")
        (load "c:/acad/common/appload.lsp")
        (and (/= (type dos_dir) 'EXSUBR)
             (xload "doslib13.exe"))
        (and (not (member "c:\\accuren2\\accurend.arx" (arx)))
             (arxload "c:/accuren2/accurend.arx")))
       ((= av "14")
        (and (not (member "doslib14.arx" (arx)))
             (arxload "doslib14.arx")))
       ((= av "15")
        (and (not (member "doslib2k.arx" (arx)))
             (arxload "doslib2k.arx")))))

 

It just so much fun keeping multiple releases running. -David

Link to comment
Share on other sites

Here's a way without needing to use DosLib at all:

(vl-load-com)
;; Function to split a string on a specified character
(defun strsplit (c str / lst p n)
 (setq n 0)
 (while (setq p (vl-string-search c str n))
   (setq lst (cons (substr str (1+ n) (- p n)) lst))
   (setq n (1+ p))
 )
 (if (< n (strlen str))
   (setq lst (cons (substr str (1+ n)) lst))
 )
 (reverse lst)
)

;; Function to list files from a wildcard match
(defun matchfiles (path / item dir match lst fil files)
 (setq path (strsplit "," path))
 (foreach item path
   (setq dir   (strcat (vl-string-right-trim "\\" (vl-filename-directory item)) "\\")
         match (substr item (1+ (strlen dir)))
         lst   (vl-directory-files dir match 1)
   )
   (foreach fil lst
     (setq files (cons (strcat dir fil) files))
   )
 )
 (reverse files)
)

And then you should change your function to something like this:

(defun c:mmbmap (/ GRDREF Drawings Dwg)
 (setvar "cmdecho" 1)
 (setq GRDREF (getstring "Enter Grid Ref [sO4522]: "))
 (setq Drawings (matchfiles (strcat "N:/CAD/2D/MappingTiles/" GRDREF "*.dwg")))
 (foreach Dwg Drawings
   (command "_.insert" Dwg "0,0,0" "1" "" "") ;This may need some fixing, not the "best" way to insert - could have problems in some instances.
 )
 (command "zoom" "o" "l" "")
 (princ)
)

BTW, that matchfiles works with multiple matches. So you can actually have something like "C:\\Temp\\*.DWG,N:\\CAD\\2D\\MappingTiles\\*.DWG" to search through both folders.

Link to comment
Share on other sites

Thanks for all your replies.

 

I have decided to go down the Non-DosLib route simply to keep everything nice and tidy on the server (although I may live to regret that).

 

I have used irneb's code to insert the maps required, and it works rather well.

 

I do, however, have to ask based on irneb's comment that the block insertation method is not completely robust why this is the case ? Always open to suggestions 8)

Link to comment
Share on other sites

Well, there's several possibilities: e.g. the "map" DWG file might have been generated using WBlock. And if so it could have been set to be scaled uniformly (or not). So the insert command would have a different number of parameters and could thus cause the whole routine to fail. There could have been placed AttDef entities in the DWG file, which would then cause the insert to ask values for these on the command line (depending on AttReq's value). Another possibility could be (highly unlikely though) that the user started this command transparently by prefixing an apostrophe (') while in another command. The insert won't work at all in this case.

 

There's probably other scenarios as well. I generally try to not use command if at all possible. Rather start looking into the ActiveX objects and use the vla/vlax methods. They're not just faster, but more "robust" for programming. Not to mention they won't show all the command-line prompts as you would get with command.

Link to comment
Share on other sites

That's fair enough.

 

I'd like to look at the ActiveX and VLA/VLAX side programming AutoCAD...but the day job of doing the drawings keeps getting in the way (you know how it is).

 

One day I'll get round to it...I've only just got my head around Lisp after a few years of trying so I'm not holding my breath while learning another large chunk of programming.

 

For the time being I'll just specify all the values in the command section as I'm not anticipating any issues in doing this. We've had all the files on the server for years so they're all fairly well tested.

 

Thanks everyone for their help, much appreciated.:D

Link to comment
Share on other sites

Yep, don't I know it! :lol: Time's always the biggest problem!

 

Anyhow, you're welcome. Glad to help ... I've been in the same boat, and these forums were where I've learnt 99% of what I know (mostly on AUGI though, but this place is perhaps even better than AUGI used to be 8)).

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