Author Topic: Opening and running a lisp program in every drawing in a directory...  (Read 9163 times)

0 Members and 1 Guest are viewing this topic.

chauny274

  • Guest
Hey guys, I'm a newbie here so try to be gentle...

I've recently made a lisp program that when called upon goes into the current dwg. and gets the titleblock and then extracts some information from it and prints it to an excel file that it creates in the directory of that dwg. It also has a loop in the program to where it always prints the info on the next new line of the excel file so that you can run it on 100 dwgs. and it won't just re-write over line 1 everytime you use it. So far everythings working great with it.

What my original plan was that I wanted it to go into the current dwg.'s directory, get all the dwg. files, open them one by one and run the program in each one then close that .dwg and move on to the next one.

I started to write another program that involves the following code:
(vl-load-com)
(setq root (getvar "DWGPREFIX"))
(setq filenamesDWG (vl-directory-files root "*.dwg"))

and then involved a foreach loop with the filenamesDWG list and for each one it would open the dwg, run my first program to get the info, then close the .dwg and move to the next one. Is there an easier way or right way of doing this cause I've tried my way for a week now and it just won't work...

Thanks in advance for any ideas!

ronjonp

  • Needs a day job
  • Posts: 7527
Re: Opening and running a lisp program in every drawing in a directory...
« Reply #1 on: December 29, 2008, 11:06:34 AM »
What you need to do is remove the current drawing from the list and run a script like so:

Code: [Select]
(defun c:batch (/ dwglist dwgname dwgpre file openfile)
  (if (and (setq dwgpre (getvar 'dwgprefix))
           (setq dwglist (vl-sort (vl-remove (strcat dwgpre (getvar 'dwgname))
                                             (mapcar '(lambda (dwgname) (strcat dwgpre dwgname))
                                                     (vl-directory-files dwgpre "*.dwg")
                                             )
                                  )
                                  '<
                         )
           )
      )
    (progn (setq openfile (open (setq file (strcat dwgpre "myscript.scr")) "w"))
           (progn (foreach f dwglist
                    (write-line (strcat "_.open \"" f "\"") openfile)
                    (write-line "audit y" openfile) ;<-- put the name of your routine on this line
                    (write-line "_.qsave _.close" openfile)
                  )
                  (close openfile)
                  (command ".script" file)
           )
           (vl-file-delete file)
    )
  )
  (princ)
)

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

Andrea

  • Water Moccasin
  • Posts: 2372
Re: Opening and running a lisp program in every drawing in a directory...
« Reply #2 on: December 29, 2008, 06:51:51 PM »
If the DWG file is open (read-Only)..the script is not working..

Code: [Select]
(defun c:batch (/ dwglist dwgname dwgpre file openfile)
  (if (and (setq dwgpre (getvar 'dwgprefix))
           (setq dwglist (vl-sort (vl-remove (strcat dwgpre (getvar 'dwgname))
                                             (mapcar '(lambda (dwgname) (strcat dwgpre dwgname))
                                                     (vl-directory-files dwgpre "*.dwg")
                                             )
                                  )
                                  '<
                         )
           )
      )
    (progn (setq openfile (open (setq file (strcat dwgpre "myscript.scr")) "w"))
           (progn (foreach f dwglist
    (if (and
  (not (Is_ReadOnly f))
  (/= (checkAttFile f) 1)
)
      (progn    
                    (write-line (strcat "_.open \"" f "\"") openfile)
                    (write-line "_.audit _y" openfile) ;<-- put the name of your routine on this line (don't forget the Unsercore_)
                    (write-line "_.qsave _.close" openfile)
    )
    )
                  )
                  (close openfile)
                  (command "_.script" file)
           )
           (vl-file-delete file)
    )
  )
  (princ)
)



;| ;;
Vérification du fichier DWL ;;
|;
;;
(defun Is_ReadOnly (rof / dwlfile dwlfile)
  (setq dwlfile (strcat (vl-filename-directory rof)
"\\"
(vl-filename-base rof)
".dwl"
)
  )
  (if (findfile dwlfile) T)
  )
)
;;
;| ;;
Vérification du fichier DWL ;;
|;



;| ;;
Vérification Attribut du fichier ;;
;;
0 = No Attributes ;;
1 = Read-Only ;;
2 = Hidden ;;
4 = System Files ;;
32 = Archive bit set ;;
64 = Link or shortcut ;;
2048 = Compressed Files ;;
|;
;;

(defun checkAttFile (file / fso)
(setq fso
       (vla-getinterfaceobject
  (vlax-get-acad-object)
  "Scripting.FileSystemObject"
       )
)
(vlax-get-property
       (vlax-invoke-method
  fso
  'getfile
  file
       )
       'Attributes
     )
)
;;
;| ;;
Vérification Attribut du fichier ;;
|;


Welcome to theswamp chauny274  ;-)
« Last Edit: December 29, 2008, 09:20:58 PM by Andrea »
Keep smile...

ronjonp

  • Needs a day job
  • Posts: 7527
Re: Opening and running a lisp program in every drawing in a directory...
« Reply #3 on: December 29, 2008, 09:31:10 PM »
Andrea,

Good addition...it might be beneficial to give the user a heads up of what did not process though. Also, your Is_ReadOnly function has one too many ending parens.

Code: [Select]
(defun c:batch (/ dwglist dwgname dwgpre file openfile uhoh len)
  (vl-load-com)
  (if (and (setq dwgpre (getvar 'dwgprefix))
   (setq dwglist (vl-sort (vl-remove (strcat dwgpre (getvar 'dwgname))
     (mapcar '(lambda (dwgname) (strcat dwgpre dwgname))
     (vl-directory-files dwgpre "*.dwg")
     )
  )
  '<
)
   )
   (setq uhoh
  "Readonly drawings will not be processed!"
   )
   (setq len (strlen uhoh))
      )
    (progn (setq openfile (open (setq file (strcat dwgpre "myscript.scr")) "w"))
   (progn (foreach f dwglist
    (if (and
  (not (Is_ReadOnly f))
  (/= (checkAttFile f) 1)
)
      (progn
(write-line (strcat "_.open \"" f "\"") openfile)
(write-line "_.audit _y" openfile)
;<-- put the name of your routine on this line (don't forget the Unsercore_)
(write-line "_.qsave _.close" openfile)
      )
      (setq uhoh (strcat uhoh "\n" f))
    )
  )
  (close openfile)
  (command "_.script" file)
  (if (= (strlen uhoh) len)
    (princ "All drawings successfully processed...")
    (alert uhoh)
  )
   )
    )
  )
  (princ)
)



 ;| ;;
Vérification du fichier DWL ;;
|;
;;
(defun Is_ReadOnly (rof / dwlfile opendwlfile)
  (setq dwlfile (strcat (vl-filename-directory rof)
"\\"
(vl-filename-base rof)
".dwl"
)
  )
  (if (findfile dwlfile)
    T
  )
)

;;
;| ;;
Vérification du fichier DWL ;;
|;



 ;| ;;
Vérification Attribut du fichier ;;
;;
0 = No Attributes ;;
1 = Read-Only ;;
2 = Hidden ;;
4 = System Files ;;
32 = Archive bit set ;;
64 = Link or shortcut ;;
2048 = Compressed Files ;;
|;
;;

(defun checkAttFile (file / fso)
  (setq fso
(vla-getinterfaceobject
   (vlax-get-acad-object)
   "Scripting.FileSystemObject"
)
  )
  (vlax-get-property
    (vlax-invoke-method
      fso
      'getfile
      file
    )
    'Attributes
  )
)
;;
;| ;;
Vérification Attribut du fichier ;;
|;

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

chauny274

  • Guest
Re: Opening and running a lisp program in every drawing in a directory...
« Reply #4 on: December 30, 2008, 09:24:01 AM »
Hmm...

I've tried out the latest code that was posted and it just wouldn't work... very odd.

On the ling that you have marked for me to put my command to run my lisp for every dwg. I put:
(write-line "_.DWGLogin") and my lisp is set up to where when I type in DWGLogin it runs the lisp. Did I do it wrong or do I need to set it up differently?

Everything else runs perfectly, it goes through every last dwg. in the directory and audits and saves them...

Thanks for all the help, even if I can't figure out why it isn't working for me at least you put me on the right direction.

EDIT: I also think it's noteworthy to point out that the resulting script file doesn't even have a line that says my lisp name. Even when I add in the code I mentioned to write it in there, it doesn't show up in the script...

lispman21

  • Guest
Re: Opening and running a lisp program in every drawing in a directory...
« Reply #5 on: December 30, 2008, 09:35:59 AM »
I believe your line to run your lisp should read (write-line "(C:DWGLogin)" openfile).  The way it goes is first you tell it your will be wrting something to the file (write-line) then specify what will be written {"(C:DWGLogin)"} and then specify the variable which holds the file that will be written too (openfile).  Maybe this will help you inthe future.

chauny274

  • Guest
Re: Opening and running a lisp program in every drawing in a directory...
« Reply #6 on: December 30, 2008, 09:59:20 AM »
I believe your line to run your lisp should read (write-line "(C:DWGLogin)" openfile).  The way it goes is first you tell it your will be wrting something to the file (write-line) then specify what will be written {"(C:DWGLogin)"} and then specify the variable which holds the file that will be written too (openfile).  Maybe this will help you inthe future.

That was it. I've been looking at too much code today if I couldn't catch that, lol.

Thanks everyone, it works great!

ronjonp

  • Needs a day job
  • Posts: 7527
Re: Opening and running a lisp program in every drawing in a directory...
« Reply #7 on: December 30, 2008, 10:51:22 AM »
Glad you got it figured out  :-)

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

chauny274

  • Guest
Re: Opening and running a lisp program in every drawing in a directory...
« Reply #8 on: December 30, 2008, 02:04:32 PM »
Sorry to bug you again guys, lol, but another problem arose and I can't figure it out...

My program works sometimes but not all the time now. Every couple of tries it will work but most of the time it returns "bad argument type: VLA-OBJECT nil". It was working yesterday for every drawing I did it on and it now it doesn't even matter which drawing I'm using it on, sometimes it works, sometimes it doesn't. The batch lisp thing that you guys showed me works great though.

Here's my code, but the functions GetExcel, GetCell, OpenExcel, PutCell, & CloseExcel, are functions that i got from a website that I got a long time ago to make it easier to place information and get information from excel sheets. They've always worked before so I don't think those are the problems.

The basic premise of this is that it goes into the dwg, figures out which of my companies title blocks we used, and then gets the information out of it and sets it onto the last line of an excel sheet. The company that we do work for has horrific standards, hence the reason that I need it to look for so many variations of title blocks and attributes.

Any ideas?
Code: [Select]
;-------------------------------------------------------------------------------
; DwgLogin - Records Data to Excel Sheet for Later Use
;-------------------------------------------------------------------------------
(defun c:DwgLogin()
(vl-load-com)
(setq CurrentRow 2)
(setq root (getvar "DWGPREFIX"))
(setq xlFile (strcat root "DrawingLogin.xls"))
(GetExcel xlFile "Sheet1" "F100")
(Setq TitleCheck (GetCell "A1"))
(if (/= TitleCheck "Dwg. Number")
     (progn (OpenExcel xlFile "Sheet1" nil)
     (PutCell "A1" (list "Dwg. Number" "Sheet" "File #" "Desc. 1" "Desc. 2" "Rev."))
     (CloseExcel xlFile)))
(while (/= "" (GetCell (strcat "C" (ITOA CurrentRow))))
     (Setq CurrentRow (+ CurrentRow 1)))
(OpenExcel xlFile "Sheet1" nil)
(PutCell (strcat "C" (ITOA CurrentRow)) (substr (GetVar "DwgName") 1 15))
(CloseExcel xlFile)
  (If (/= nil (ssget "_X" (list '(0 . "INSERT") (cons 2 "S-TITLE"))))
        (setq TitleBlock "S-TITLE")
  ); **END IF**
  (if (/= nil (ssget "_X" (list '(0 . "INSERT") (cons 2 "DTITLE"))))
        (setq TitleBlock "DTITLE")
  ); **END IF**
  (if (/= nil (ssget "_X" (list '(0 . "INSERT") (cons 2 "TITLE"))))
        (setq TitleBlock "TITLE")
  ); **END IF**
(setq ss (ssget "_X" (list '(0 . "INSERT") (cons 2 TitleBlock)))) ; RETURNS SS CODE
(if (not ss) (quit))
(OpenExcel xlFile "Sheet1" nil)
(setq Edata (entget (setq e (ssname ss 0)))) ; GETS DXF SET FOR SS CODE
(while (/= (cdr (assoc 0 Edata)) "SEQEND")
(if (= (cdr (assoc 0 Edata)) "ATTRIB")
       (cond ((= (cdr (assoc 2 Edata)) "DWGNO.") (PutCell (strcat "A" (ITOA CurrentRow)) (cdr (assoc 1 Edata)))) ; COND TO PICK ATTRIBUTES
        ((= (cdr (assoc 2 Edata)) "DwgNo.") (PutCell (strcat "A" (ITOA CurrentRow)) (cdr (assoc 1 Edata))))
((= (cdr (assoc 2 Edata)) "DWGNO") (PutCell (strcat "A" (ITOA CurrentRow)) (cdr (assoc 1 Edata))))
((= (cdr (assoc 2 Edata)) "DwgNo") (PutCell (strcat "A" (ITOA CurrentRow)) (cdr (assoc 1 Edata))))
((= (cdr (assoc 2 Edata)) "WGNO") (PutCell (strcat "A" (ITOA CurrentRow)) (cdr (assoc 1 Edata))))
((= (cdr (assoc 2 Edata)) "LINE2") (PutCell (strcat "D" (ITOA CurrentRow)) (cdr (assoc 1 Edata))))
((= (cdr (assoc 2 Edata)) "LINE3") (PutCell (strcat "E" (ITOA CurrentRow)) (cdr (assoc 1 Edata))))
((= (cdr (assoc 2 Edata)) "REVNO.") (PutCell (strcat "F" (ITOA CurrentRow)) (cdr (assoc 1 Edata))))
((= (cdr (assoc 2 Edata)) "REVNO") (PutCell (strcat "F" (ITOA CurrentRow)) (cdr (assoc 1 Edata))))
((= (cdr (assoc 2 Edata)) "REV") (PutCell (strcat "F" (ITOA CurrentRow)) (cdr (assoc 1 Edata))))
    )
)
(setq Edata (entget (setq e (entnext e))))
) ;WHILE
(CloseExcel xlFile)
)



**EDIT**: Got it to work, apparently I just needed a progn in the then section of an if statement. I don't know why it would work on some and not others, but oh well. Thanks everybody, couldn't have gotten this done without yall.
« Last Edit: January 04, 2009, 10:03:48 AM by chauny274 »

andr3flaviano

  • Guest
Re: Opening and running a lisp program in every drawing in a directory...
« Reply #9 on: October 06, 2016, 11:46:10 AM »
Guys, I have to do almost the samething, but i need to execute a function with a previously defined parameter in Multiple DWG's.
I've tried  to write a code, but it didn't work:

The function that i have to call is:

Txt ( / tval ), where ' tval ' is a number

The code to execute that function in every DWG in directory is the same:

(defun c:alterat (/ dwglist dwgname dwgpre file openfile uhoh len)
  (vl-load-com)
  (if (and (setq dwgpre (getvar 'dwgprefix))
      (setq dwglist (vl-sort (vl-remove (strcat dwgpre (getvar 'dwgname))
                    (mapcar '(lambda (dwgname) (strcat dwgpre dwgname))
                       (vl-directory-files dwgpre "*.dwg")
                    )
              )
              '<
          )
      )
      (setq uhoh
        "Readonly drawings will not be processed!"
      )
      (setq len (strlen uhoh))
      )
    (progn (setq openfile (open (setq file (strcat dwgpre "myscript.scr")) "w"))
            (setq num (getstring t "\nType the number ")) ; <-- Here the function asks the number
      (progn (foreach f dwglist
          (if   (and
           (not (Is_ReadOnly f))
           (/= (checkAttFile f) 1)
         )
            (progn
         (write-line (strcat "_.open \"" f "\"") openfile)
         (write-line"(C:txt num)" openfile)   ; <-- here the function txt should be executed with the parameter tval = num. But it didn't work...
         (write-line "_.qsave _.close" openfile)
            )
            (setq uhoh (strcat uhoh "\n" f))
          )
        )
        (close openfile)
        (command "_.script" file)
        (if (= (strlen uhoh) len)
          (princ "All drawings successfully processed...")
          (alert uhoh)
        )
      )
    )
  )
  (princ)
) ; End Defun

Could Someone help me, please?
« Last Edit: October 06, 2016, 12:03:52 PM by andr3flaviano »