mjavy7 Posted April 18, 2013 Posted April 18, 2013 Hello All. I need help with AutoCAD 2013 I have multiple drawings with 100's of tabs inside, I would like to either export or print out all of the tab names. If anyone knows a way to do this, I would love to hear about it. Thank you in advanced, Javier Quote
BlackBox Posted April 18, 2013 Posted April 18, 2013 Here's a simple example for the active document: (defun c:Tabs () (prompt "\nTab Names: ") (foreach layout (layoutlist) (print layout) ) (princ) ) Quote
mjavy7 Posted April 18, 2013 Author Posted April 18, 2013 now how do I use this? LOL Sorry man, this is a bit over my head. If you could please explain how to use this code, I would highly appreciate it. If there is already a place in here were it is explained let me know and I will go there to learn. Quote
BlackBox Posted April 18, 2013 Posted April 18, 2013 (edited) No worries; we all start somewhere. First, to use LISP code posted on forums, simply copy + paste the code into an empty text file, and save with a .LSP file extension. See this tutorial for loading LISP routines. After posting that quick sample above, I re-read your post, and saw that you said you're needing to process multiple drawings, so I thought I'd provide a 'Batch Report' routine... Once you've created the LISP file, and loaded the code into your drawing, simply invoke by entering BFINDTABS EXPORTLAYOUT Command. [Edit :: 2013-04-19] Modified code to allow for Active (current drawing), or Browse (single/multiple drawing) selection. I have added a DOSLIB dependency specifically to gain access to multiple file selection offered by DOS_GETFILEM function. Please download DOSLIB here, and use ARXLOAD to load your version's ARX file. This modification also provides a LISP callable function BBOX:ExportLayout. Multiple miscellaneous items corrected as well, such as non-localized variable, and non-essential code included by mistake when pulling from another routine. Additional handling needed for open / read-only Documents. (vl-load-com) (defun BBOX:ExportLayout (dwgs / *error* BBOX:GetDate BBOX:GetTime BBOX:WriteData acApp oDocuments oShell path filePath dbxDoc file openDoc oLayouts layoutName ) (defun *error* (msg) (if file (close file) ) (if oShell (vlax-release-object oShell) ) (if dbxDoc (vlax-release-object dbxDoc) ) (cond ((not msg)) ; Normal exit ((member msg '("Function cancelled" "quit / exit abort"))) ; <esc> or (quit) ((princ (strcat "\n** Error: " msg " ** "))) ; Fatal error, display it ) (princ) ) (defun BBOX:GetDate (date) (setq date (mapcar '(lambda (x) (itoa x)) date)) (strcat (nth 0 date) "-" (nth 1 date) "-" (nth 3 date)) ) (defun BBOX:GetTime (date / hr mn) (setq hr (nth 4 date)) (setq mn (itoa (nth 5 date))) (if (= 1 (strlen mn)) (setq mn (strcat "0" mn)) ) (cond ((> 12 hr) (strcat (itoa hr) ":" mn " AM")) ((strcat (itoa (- hr 12)) ":" mn " PM")) ) ) (defun BBOX:WriteData (path dwg layoutName file / filePath date) (write-line (vl-string-right-trim "," (apply 'strcat (mapcar '(lambda (x) (strcat x ",")) (list (setq filePath (strcat path dwg)) (if (setq date (vl-file-systime filePath)) (BBOX:GetDate date) "{ Read-Only }" ) (if date (BBOX:GetTime date) "{ Read-Only }" ) layoutName ) ) ) ) file ) ) (if (and (setq acApp (vlax-get-acad-object)) (setq oDocuments (vla-get-documents acApp)) (setq oShell (vla-getinterfaceobject acApp "Shell.Application" ) ) (setq path (car dwgs)) (setq filePath (strcat (vl-filename-directory (vl-filename-mktemp) ) "\\Export Layout Report_" (menucmd "M=$(edtime,$(getvar,date),YYYY-MO-DD)" ) ".csv" ) ) (princ "\nWorking, please wait...") (princ) (setq dbxDoc (vla-getinterfaceobject acApp (strcat "ObjectDBX.AxDbDocument." (substr (getvar 'acadver) 1 2) ) ) ) ) (progn (setq file (open filePath "w")) (write-line "Directory Searched:" file) (write-line path file) (write-line "" file) (write-line "Drawing:,Date:,Time:,Layout Name:" file) (foreach dwg (cdr dwgs) (if (not (vl-catch-all-error-p (setq openDoc (vl-catch-all-apply 'vla-item (list oDocuments dwg) ) ) ) ) (setq oLayouts (vla-get-layouts openDoc)) (progn (vl-catch-all-apply 'vla-open (list dbxDoc (strcat path dwg)) ) (setq oLayouts (vla-get-layouts dbxDoc)) ) ) (vlax-for oLayout oLayouts (if (/= "Model" (setq layoutName (vla-get-name oLayout))) (BBOX:WriteData path dwg layoutName file) ) ) ) (princ "Done.") (princ) (setq file (close file)) (vlax-invoke oShell 'open filePath) (*error* nil) ) (cond (filePath (*error* "Unable to create \"ObjectDBX.AxDbDocument\" Object" ) ) (acApp (*error* "Unable to create \"Shell.Application\" Object") ) ) ) ) (defun c:ExportLayout (/ opt dwgs) (initget "Active Browse") (if (not (setq opt (getkword "\nWhat drawing would you like to process [Active/Browse]<Active>: " ) ) ) (setq opt "Active") ) (cond ((= "Active" opt) (if (= 1 (getvar 'dwgtitled)) (BBOX:ExportLayout (list (getvar 'dwgprefix) (getvar 'dwgname)) ) (prompt "\n** Drawing not saved ** ") ) ) ((= "Browse" opt) (if (setq dwgs (dos_getfilem "Select Drawings" (getvar 'dwgprefix) ;<-- default path here "Drawing files (*.dwg)|*.dwg" ) ) (BBOX:ExportLayout dwgs) ) ) ) (princ) ) Inspired by a favorite routine of mine, BFIND, from Lee. Edited April 19, 2013 by BlackBox Quote
mjavy7 Posted April 18, 2013 Author Posted April 18, 2013 You are the man!! They both work great but I must say the second one is very impressive!!! This is exactly what I need!!! Quote
BlackBox Posted April 18, 2013 Posted April 18, 2013 That is kind of you to say; I'm happy to help ... I've had a lot of help along the way. Quote
mjavy7 Posted April 18, 2013 Author Posted April 18, 2013 Here's a simple example for the active document: (defun c:Tabs () (prompt "\nTab Names: ") (foreach layout (layoutlist) (print layout) ) (princ) ) How hard is to make this code export the list to excel like the second code? Quote
BlackBox Posted April 18, 2013 Posted April 18, 2013 How hard is to make this code export the list to excel like the second code? You mean, where it only prompts for a single drawing, rather than a directory of? Or do you mean no prompt at all; as in it only works on the drawing open when invoked? Quote
BIGAL Posted April 19, 2013 Posted April 19, 2013 A very simplified version (defun c:Tabs () (setq fname "C:\acadtemp\mytabs") (setq fo (open fname "w")) (prompt "\nTab Names: ") (foreach layout (layoutlist) (print layout) (write-line layout fo) ) (close fo) (princ) ) ;just open file mytabs in excel Quote
mjavy7 Posted April 19, 2013 Author Posted April 19, 2013 You mean, where it only prompts for a single drawing, rather than a directory of? Or do you mean no prompt at all; as in it only works on the drawing open when invoked? Either way it works for me, what ever is easier for you. I can work with either. Quote
mjavy7 Posted April 19, 2013 Author Posted April 19, 2013 A very simplified version Thank you. This one works but adds a few steps to my process. Since I have to do many files, I have to go thru explorer, copy file to different location, rename and modify. The previous code (BTABS) automatically spits out and excell file ready for saving which makes it more user friendly. I am not trying to discredit your effort....I do appreciate it. Quote
BlackBox Posted April 19, 2013 Posted April 19, 2013 Either way it works for me, what ever is easier for you. I can work with either. Why pick one, when you can do both... Code revised here... Please read the [Edit ...] Comments closely. Quote
BlackBox Posted April 19, 2013 Posted April 19, 2013 The previous code (BTABS) automatically spits out and excell file ready for saving which makes it more user friendly. Just to clarify, the code I offered actually generates a .CSV file, and uses Shell.Application to open the resultant file in one's own default application for .CSV files... In your case, that's Excel, others who do not have Office may find that Notepad opens the file, etc.... That's the part I credit my learning to Lee (not that he invented it, the code was there before his time, but I personally learned this 'trick' from him ). In any event, I hope that makes (more?) sense to you now. Quote
mjavy7 Posted April 19, 2013 Author Posted April 19, 2013 [Edit :: 2013-04-19] Modified code to allow for Active (current drawing), or Browse (single/multiple drawing) selection. I have added a DOSLIB dependency specifically to gain access to multiple file selection offered by DOS_GETFILEM function. Please download DOSLIB here, and use ARXLOAD to load your version's ARX file. Ok, this is also a bit over my head so here is what I got so far: 1. I created a *.lsp file with the code provided 2. I went to the link and downloaded the DOSLIB files and double cliked in the *.EXE file. 3. In Auto CAD loaded my new *.lsp file and added the folder to the support search path. The part that looses me is the ARX... is shouls I rename the *.lsp to *.ARX? and in autocad loaded with the ARX command? Quote
BlackBox Posted April 19, 2013 Posted April 19, 2013 Ok, this is also a bit over my head so here is what I got so far:1. I created a *.lsp file with the code provided 2. I went to the link and downloaded the DOSLIB files and double cliked in the *.EXE file. 3. In Auto CAD loaded my new *.lsp file and added the folder to the support search path. The part that looses me is the ARX... is shouls I rename the *.lsp to *.ARX? and in autocad loaded with the ARX command? See the ARXLOAD function (linked above) to load DOSLIB's ARX file... Then the dependent function (dos_getfilem) will be available... Either use the DOSLIB Command, or an ARXLOAD call in your Acad.lsp to ensure that DOSLIB's ARX file is loaded each time you start AutoCAD. ** Note - ObjectARX files (C++ for AutoCAD), like .NET assemblies, need only be loaded once per session, so no need to add to AcadDoc.lsp Quote
mjavy7 Posted April 19, 2013 Author Posted April 19, 2013 I am doing something work and I dont know what... Command: EXPORTLAYOUT What drawing would you like to process [Active/Browse]: B Working, please wait... ** Error: bad argument type: consp nil ** Command: ...I choose the drawing file that I need and it comes back with a bad argument. Any advise? Quote
BlackBox Posted April 19, 2013 Posted April 19, 2013 While successful in my limited tests, I always chose files that were not read-only... It appears that the routine doesn't obtain SysTime on read-only files... Looking at a work around and will post back shortly. Quote
BlackBox Posted April 19, 2013 Posted April 19, 2013 Problem fixed. ... Revised code here. The issue was in handling Documents that were either already open in one's own session, or those read-only (open by others) causing vl-File-SysTime to return Nil. So, I built in some checking for that, but then needed to add some code to check for Documents open in one's own session to also avoid attempts to open a second time (it's already open, and then ObjectDBX tries to open which caused some undesirable results). Again, all fixed AFAIK, so please let me know what issues (if any) you might encounter... I may come back to streamline a bit, but that will come later. Sorry for any confusion. Cheers Quote
juanjrvn Posted May 28, 2015 Posted May 28, 2015 Hello! I know this is a couple years old, but the solution offered by BlackBox works for me. Thank you. Hopefully you're all still around and will respond. When using the "browse" option, is it possible to select a top-level folder and process all the drawing files within it and all its sub-folders? I have about 27,000 files whose layout tab names I'd like to export, but they exist in a mess of folders, sub-folders, and so on. Thanks again! Juan Quote
BlackBox Posted May 29, 2015 Posted May 29, 2015 Hello! I know this is a couple years old, but the solution offered by BlackBox works for me. Thank you. Hopefully you're all still around and will respond. When using the "browse" option, is it possible to select a top-level folder and process all the drawing files within it and all its sub-folders? I have about 27,000 files whose layout tab names I'd like to export, but they exist in a mess of folders, sub-folders, and so on. Thanks again! Welcome to CADTutor! I'm glad you found the code helpful. Yes, the code could be revised to iterate all drawings in all sub-directories using ObjectDBX, however I would advise against this due to the fact that it would essentially lock up your session, overflowing the memory stack, or even if successful, would take an immeasurable amount of time depending on workstation specs. That said, it is technically possible using LISP... If you're serious about actually wanting to process that amount of data, I'd instead suggest we power this functionality over to .NET API for performance gains alone, let alone the ability to batch process in parallel (multiple instances at once), in addition to in series (one-at-a-time). Just turning in for a few hours of shut eye, as I have to be back at the office soon, but wanted to make this quick reply. Cheers Quote
Recommended Posts
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.