Sharper Posted January 5, 2023 Posted January 5, 2023 Hi Guys Newbie here, I've seen this community a few times over the years and I love the help that you guys give, either by guiding someone through their code, or by creating some great examples of code that fulfil someone's request. I have a little knowledge in autolisp, I can create small programs for my needs, or I can adapt some large programs that would do what I need. I'm hoping I can grow my knowledge and also pass on anything I have as you guys do. For today, I have a question, its more of a starting point for me really.. (i haven't come across anything like this in my searches) What I'm looking to do is 1. Get the current drawing name ( I know I can do this with Autolisp ) 2. Save the current drawing, then start a new drawing. (could be done via Autolisp or script) 3. Insert the prior drawing into this new drawing as a block (not sure if Autolisp or script can work between 2 drawings) The reason for this is, is that I can do many jobs (say 15-20) that are 90% similar to each other. I create the 1st from scratch, at the end of it I will save this file, then start a new one and insert in the previous and make the changes etc etc Now, to explain, I use a lot of xdata on my files, some of this xdata is assigned to the geometry, and this is kept from file to file. Other xdata is saved in the drawing file itself and is unique to each file, so i don't need to keep this data. And this is why I insert the previous file into a new drawing rather than just continuing and saving as a new file name. Because when i start new and insert, it keeps all the xdata on the geometry but loses the xdata from the file which is perfect for my needs. My issue with my method i'm current using is, if i'm disturbed, by call or something, I forget what job name I had previously, so I have to look it up before I can insert it into the new drawing. It doesn't sound like much, but boy does it grate, especially on very busy days. My question then is Can this be done completely in Autolisp (or visual lisp), if not can it be done via script, would it require both to be used? If anyone knows if this is possible and could point me in the right direction to get me started, that would be awesome. Quote
mhupp Posted January 5, 2023 Posted January 5, 2023 All you would have to do is open old project and save it to a new location & filename? or am i missing something. Quote I use a lot of xdata on my files, some of this xdata is assigned to the geometry, and this is kept from file to file. Other xdata is saved in the drawing file itself and is unique to each file, so i don't need to keep this data. And this is why I insert the previous file into a new drawing rather than just continuing and saving as a new file name. Because when i start new and insert, it keeps all the xdata on the geometry but loses the xdata from the file which is perfect for my needs. This should delete all xdata from selected items in the drawing. (untested and use on copy of drawing only) (defun C:DeleteXData (/ ss ent) (if (setq ss (ssget '((-3 ("*"))))) (foreach ent (vl-remove-if 'listp (mapcar 'cadr (ssnamex SS))) (entmod (list (cons -1 ent) (list -3 (list "*")))) ;change * to appname ) ) (princ) ) Quote
Steven P Posted January 5, 2023 Posted January 5, 2023 If you are doing this as you say, your problems will start when you try to work on a drawing that didn't run the LISP from. It is possible to get the filename and do a save from one drawing, I think (I haven't done this) you can also create a new drawing from another but as soon as you do you end the LISP. It would also be possible to copy modelspace or paperspace to clipboard (command "copybase" "0,0" (ssget "X") "" ) and then in the new drawing paste that in (so long as you haven't copied anything else to the clipboard in between) In a second LISP it would be possible to set up the basic drawing parameters, even things such as insert or create and populate a border, set up pages, load fonts and line types as needed, and then paste from the clipboard (so long as you keep CAD open and don't copy anything else to the clipboard in between) It might be possible as a 2 stage process but I don't know how much that would save you from doing it manually? Would Lee Macs Steal LISP be any use? (http://www.lee-mac.com/steal.html) Quote
Sharper Posted January 5, 2023 Author Posted January 5, 2023 Hey mhupp Thanks for the reply. The issue with this lisp is i do not wish to lose the xdata on any of the geometry, its this i want to keep (contains data used by my Cam software for CNC file creation). I also have xdata saved in the drawing itself (not attached to any geometry), this xdata holds the customer order information within the actual drawing file, and its this xdata that is unique per drawing, so this is what I want to lose. However, with that said, this lisp will come in very handy on some of my other work types where I export files to my customer (and they're not needing that xdata) which would make the file size a lot smaller. Quote
Sharper Posted January 5, 2023 Author Posted January 5, 2023 Hey StevenP Quote If you are doing this as you say, your problems will start when you try to work on a drawing that didn't run the LISP from. It is possible to get the filename and do a save from one drawing, I think (I haven't done this) you can also create a new drawing from another but as soon as you do you end the LISP Yes, this is what i thought, and wondered if it would instead need to be called from a script which can run between 2 drawings i believe!? (not sure if a script and Autolisp can be used together) Quote It would also be possible to copy modelspace or paperspace to clipboard (command "copybase" "0,0" (ssget "X") "" ) and then in the new drawing paste that in (so long as you haven't copied anything else to the clipboard in between) In a second LISP it would be possible to set up the basic drawing parameters, even things such as insert or create and populate a border, set up pages, load fonts and line types as needed, and then paste from the clipboard (so long as you keep CAD open and don't copy anything else to the clipboard in between) I see what you mean about copying to the clipboard and then back after creating a new file, the issue with that is it only takes from what is shown on screen, and not any blocks that are saved within the drawing (if i did it correctly), but even so it seems like more steps that I currently use...Although it does help that I wouldn't need to remember the file name, I may have to look more into this i think. Quote Would Lee Macs Steal LISP be any use? (http://www.lee-mac.com/steal.html) I will have to take a look and try the steel.lsp tomorrow, from what i read it sounds like what i need, being able to grab everything into a new file. I suppose it just depends on how many extra steps it needs, if more than i currently do, best way to find out is to give it a try.. Thanks for the help guys, i'll be back with some results 1 Quote
Sharper Posted January 5, 2023 Author Posted January 5, 2023 Just a quick one.... Is it at all possible to pass a variable into a script ? Like for example could i create a script that first runs a lisp which gets the current file name then could that file name be passed back to the script which then could start a new drawing and insert the file via the name? I've probably over simplified this, and i'm very doubtful if that indeed could work.. or.... (my spidy senses are tingling now) Could the script first call a lisp in the 1st drawing to get the drawing name and save it to a text file then the script starts a new drawing, then it calls a second lisp that reads the text file and inserts using that number? Quote
Steven P Posted January 5, 2023 Posted January 5, 2023 Script could work to copy blocks, you might need to make them visible as a part of the process but try Steal and see how that works? Quote
Steven P Posted January 5, 2023 Posted January 5, 2023 Yes, for a script file the one I use the most ( a batch script) the file is made up 'on the fly'. Simply put a text file saved with a .scr suffix. Since it is made up when I need it you can put any text string in there. In my case this is the file names to do the back on, and the commands (and LISPs) to run... which change every time. To go script route for your Spidey senses you can set it running in file 1, create the script file and as a part of that pass the filename to the new file (I think). One thing I use is that the script file name is always the same name saved in my temp files folder. You can also do a similar idea, create a temporary text file with the settings you want to copy - keeping the file names the same makes the LISP easier. Continue on the 2nd file and have a command to read this temp text file and get the data. My script is something like this - noting that each file (this is for a batch) has the same things happening but there is no reason why you can do different things on each file (load "C:\\Users\\AppData\\Local\\Temp\\batchscrlisps.lsp") ;; ensures LISPS are loaded LOAD "C:\USERS\DESKTOP\AUTOCAD\AUTOCAD LISPS\TEXTLISPS.LSP" ;; ensures LISPS are loaded TXTFILENAMETT ;; LISP to run LOAD "C:\USERS\DESKTOP\AUTOCAD\AUTOCAD LISPS\TEXTLISPS.LSP" ;;ensure next LISP is loaded TXTCBNEW ;;Run next LISP (0,0) ;;Data that the LISP above askes for _.OPEN "C:\Users\Desktop\temp.dwg" ;;Open next drawing (load "C:\\Users\\AppData\\Local\\Temp\\batchscrlisps.lsp") LOAD "C:\USERS\DESKTOP\AUTOCAD\AUTOCAD LISPS\TEXTLISPS.LSP" TXTFILENAMETT LOAD "C:\USERS\DESKTOP\AUTOCAD\AUTOCAD LISPS\TEXTLISPS.LSP" TXTCBNEW (0,0) _.OPEN "C:\Users\Desktop\temp.dwg" (vla-close (vla-item (vla-get-documents (vlax-get-acad-object)) "temp.dwg") :vlax-false) ;;Close previous drawing (load "C:\\Users\\AppData\\Local\\Temp\\batchscrlisps.lsp") ;;and repeat LOAD "C:\USERS\AUTOCAD\AUTOCAD LISPS\TEXTLISPS.LSP" TXTFILENAMETT LOAD "C:\USERS\DESKTOP\AUTOCAD\AUTOCAD LISPS\TEXTLISPS.LSP" TXTCBNEW (0,0) (vla-SendCommand (vla-get-ActiveDocument (vlax-get-acad-object)) "(c:batchclose) ") The original drawing isn't closed but can be right at the end. This works by run process on open drawing, open drawing 2, do stuff, open drawing 3, close drawing 2, do stuff to 3, repeat, close last drawing and return to 1. Hope that makes some sort of sense - there are better descriptions out there but this could work for you Quote
mhupp Posted January 5, 2023 Posted January 5, 2023 53 minutes ago, Sharper said: The issue with this lisp is i do not wish to lose the xdata on any of the geometry, its this i want to keep (contains data used by my Cam software for CNC file creation). I also have xdata saved in the drawing itself (not attached to any geometry), this xdata holds the customer order information within the actual drawing file, and its this xdata that is unique per drawing, so this is what I want to lose. Yeah it was kinda hard to follow what your saying. This is what your wanting to do? xdata about current project but not linked to any entities in the drawing (remove) xdata linked to entities in the drawing (keep) Still think the easiest thing to do would be saving as new project. then clear old project xdata not linked to entities. no need for multiple drawings, blocks, inserting. See if this works. on clearing the project xdata. if so ill add a save function that will allow you to pick there to save. (defun C:Foo (/ ss) (vl-load-com) (if (setq ss "_X" (ssget)) (command "_.Cutclip" SS "") (C:DeleteXData) ;use old lisp (command "_.Pasteclip" '(0.0 0.0 0.0)) ;paste back in entitys & xdata? ) (princ) ) 1 Quote
Sharper Posted January 5, 2023 Author Posted January 5, 2023 Thanks guys, Plenty for me to look over, and trial 1 Quote
Sharper Posted January 6, 2023 Author Posted January 6, 2023 Hi mhupp I'm not sure what the issue is, but when I "appload" in the lisp above i get an error message "Autolisp Error:syntax error", it looks okay to me but I am a novice lol I've been using the "steal.lsp" today, its an awesome piece of code, and using the "StealAll" command it does what i need, and its better than my current method. If I had 1 wish, it would be, instead of me having to choose the drawing to steal from, as per my needs it would always choose the newest file in a specific directory, thereby shortening the process. I'm not sure if this is within my current level of knowledge to do, but i've got a weekend to give it a try (if you don't mind me making changes to your lisp file @Lee Mac? I won't try to make any changes without your approval mate, I appreciate all the time and effort that goes into these projects) 1 Quote
Sharper Posted January 6, 2023 Author Posted January 6, 2023 (edited) StevenP I like the scripting that you've shown I've only ever done basic scripts, I did not realize that Visual-lisp could be used in script but i suppose anything that can be passed at the command line can be in a script file... It just never occurred to me that it could be more than just basic commands I'll definitely be looking to improve on some of my existing scripts from now on.... I'm really glad I opened this thread on here... I've got so much extra information and knowledge already (and now given myself more work to do haha but for the good for future work) Edited January 6, 2023 by Sharper 1 Quote
mhupp Posted January 6, 2023 Posted January 6, 2023 34 minutes ago, Sharper said: If I had 1 wish, it would be, instead of me having to choose the drawing to steal from, as per my needs it would always choose the newest file in a specific directory, thereby shortening the process. This will create a list of files in the given folder from newest to oldest. (setq FilSys (vlax-create-object "Scripting.FileSystemObject") path "C:\\Folder\\path" ) (foreach F (vl-directory-files path "*.DWG" 1) (setq FilObj (vlax-invoke FilSys 'GetFile (strcat path "\\" F)) DatMod (vlax-get FilObj 'DateLastModified) lst (cons (cons F DatMod) lst) ) ) (vlax-release-object FilObj) (vlax-release-object FilSys) (setq lst (mapcar '(lambda (l) (car (nth l lst))) (vl-sort-i lst '(lambda (d1 d2) (> (cdr d1) (cdr d2)))))) (setq nfile (car lst)) ;newest file in folder ;(setq nfilepath (strcat path "\\" (car lst))) or if you need the full path 2 Quote
Steven P Posted January 6, 2023 Posted January 6, 2023 1 hour ago, Sharper said: I'm not sure if this is within my current level of knowledge to do, but i've got a weekend to give it a try (if you don't mind me making changes to your lisp file @Lee Mac? I won't try to make any changes without your approval mate, I appreciate all the time and effort that goes into these projects) Lee Mac doesn't post as much as he used to (which is a real shame, every time he does we all learn something). I suspect he lurks in the background. Watching. Reading his posts I suspect if you study his code, learn, understand and then modify it to suit yourself he would be more than happy that he taught you something new also. I haven't looked at the Steal LISP, accepting it works well for me. Might be that you'd want to take out the file selection part into a separate LISP (Lee Mac calls this idea a wrapper) which then passes the file details to the steal command? get that working - make sure you have the code correct - and then use MHUPP above to make a new LISP, selecting the latest file to use. You get 2 LISPs then, classic steal and newest file steal both using the same basic code Depends how the afternoon goes it might interest me to look at this to give you some hints - first week after the new year, half the Engineers are on holiday, it might be quiet. 1 Quote
Sharper Posted January 6, 2023 Author Posted January 6, 2023 Thanks guys Yeah, I see where this could go now... Thanks Mhupp for that snippet of code, and yeah if you have time StevenP some hints would be appreciated. Don't worry if you don't have time, your last post and Mhupps post has given me a great starting point to play with. 2 Quote
Steven P Posted January 6, 2023 Posted January 6, 2023 2 hours ago, Sharper said: I'm not sure if this is within my current level of knowledge to do, but i've got a weekend to give it a try (if you don't mind me making changes to your lisp file @Lee Mac? I won't try to make any changes without your approval mate, I appreciate all the time and effort that goes into these projects) This looks easier than I though. There are a few options for steal, such as below, StealLast (which steals from the last drawing you stole from) Each of these options have this line (steal <dwg> <lst> ) which calls the main routine.... so use MHUPPs latest drawing to get the drawing name (and filepath, probably taking note of double \\ in there too), then simple (steal MyDrawing.dwg) will bring up the dialogue box to select what to steal. if you also look at the StealAll LISP this will give you a clue at what to do to set what to steal each time (a few fewer button presses and dialogue box) Play with it over the weekend! (defun c:StealLast nil (Steal (if (setq dwg (getenv "LMac\\StealLast")) (findfile dwg) ) nil ) ) MHUPP - going to 'steal' what you did for something else that has been in the back of my mind for ages, a batch process selecting that days work for example to plot or PDF what I have done, think DatMod (vlax-get FilObj 'DateLastModified) will do the trick! 1 1 Quote
Sharper Posted January 6, 2023 Author Posted January 6, 2023 Thanks yes I will definitely have some fun with this over the weekend ( Also gives me a chance of getting out of visiting the in laws haha i hope) 1 Quote
mhupp Posted January 6, 2023 Posted January 6, 2023 14 minutes ago, Steven P said: MHUPP - going to 'steal' what you did for something else that has been in the back of my mind for ages, a batch process selecting that days work for example to plot or PDF what I have done, think DatMod (vlax-get FilObj 'DateLastModified) will do the trick! That's the first part of code I use to list all the autosave files from the temp folder. then feed it into @BIGAL's listselect. Good for when the drawing crashed and you want to get the last autosave. 1 Quote
BIGAL Posted January 6, 2023 Posted January 6, 2023 Correct credit for list select, "This is the one I use by Alan Thompson". 1 Quote
Sharper Posted January 10, 2023 Author Posted January 10, 2023 i have it working guys, so long story short, i should have read "ALL" of the header test of the Steal.lsp, and not just some (lesson learned the hard way, but learned non the less).. So Lee has already made this lisp program accessible as a sub function also So with the following code (tweaked from mhupp's above... my thanks once more) it now does exactly what I need from a new page (defun c:GetLastFile (/ Filsys FilObj DatMod lst nfilepath) (setq FilSys (vlax-create-object "Scripting.FileSystemObject") path "C:\\Workflow" ) (foreach F (vl-directory-files path "*.DWG" 1) (setq FilObj (vlax-invoke FilSys 'GetFile (strcat path "\\" F)) DatMod (vlax-get FilObj 'DateLastModified) lst (cons (cons F DatMod) lst) ) ) (vlax-release-object FilObj) (vlax-release-object FilSys) (setq lst (mapcar '(lambda (l) (car (nth l lst))) (vl-sort-i lst '(lambda (d1 d2) (> (cdr d1) (cdr d2)))))) ;(setq nfile (car lst)) ;newest file in folder (setq nfilepath (strcat path "\\" (car lst))) ;or if you need the full path (Steal nfilepath '( ( "Blocks" ("*") ) ( "Layers" ("*") ) ( "Dimension Styles" ("*") ) ( "Text Styles" ("*") ) ( "Multileader Styles" ("*") ) ) ) (Princ "\nPrior Order Data import finished") (princ) ) My thanks again to everyone that helped... You guys rock! 2 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.