Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

move bak files to project's subfolder

24 REPLIES 24
SOLVED
Reply
Message 1 of 25
Klingi162
3876 Views, 24 Replies

move bak files to project's subfolder

Hey guys,

 

I'm always annoyed with the many .bak files within a projects folder and manually move it to a subfolder to bring everything in order.

Now I was thinking that this whould be way easier if this would work with lisps, the only thingis that I have no clue how! Smiley Frustrated

 

I know, that there is the simple way, to move all .bak files to one global folder with the express tool "movebak", but I don't want to put it in one folder only.

 

my project is for example located in "c:\project_a\plan_a.dwg", so I want to create a subfolder in "c:\project_a\bak\plan_a.bak"

 

maybe you lisps-genii can help me with this issue! Smiley Happy

 

cheers klingi

24 REPLIES 24
Message 2 of 25
gilsonrss
in reply to: Klingi162

Hi Klingi.


I am Brazilian and my English is very bad (I'm sorry for that).
I did here a little routine to do what you asked. I hope that is what you were needing.

 

graciously 
Gilson

 

 

(defun grab_bak_file ( / path name name_bak path_bak)
(setq path (getvar "dwgprefix"))
(setq name (getvar "dwgname"))
(setq name_bak (strcat (vl-filename-base name) ".bak"))
(setq path_bak (strcat path name_bak))
;Check to file exists
(if (vl-file-size path_bak)
path_bak
nil
)
)

(defun move_bak_file (path / temp_name temp_path dir_bak)
(setq temp_name (vl-filename-base path))
(setq temp_path (vl-filename-directory path))
;Check to dir bak exists
(if (not (setq dir_bak (vl-directory-files temp_path "bak" -1)))
(if (not (vl-mkdir (strcat temp_path "\\bak")))
(progn
(alert "\nError: Error to creat dir bak")
(exit)
)
)
)
(setq dir_bak (strcat temp_path "\\bak\\"))
;Delete bak old
(vl-file-delete (strcat dir_bak temp_name))

(if (not (vl-file-rename path (strcat dir_bak temp_name)))
(progn
(alert "\nError: Error to move file bak")
(exit)
)
)
)

(defun c:movebak ( / decho_old path_bak)

(setq decho_old (getvar "cmdecho"))
(setvar "cmdecho" 0)

;Function grab file .bak with same name
(setq path_bak (grab_bak_file))
(if path_bak
(progn
(move_bak_file path_bak)
(prompt "\nFile moved")
)
(prompt "\nNot file to move")
)
(setvar "cmdecho" decho_old)
)

(prompt "\nmovebak - to move bak file")

 

 

Message 3 of 25
Lee_Mac
in reply to: Klingi162

Try the following Klingi:

 

(defun c:baksub ( / dir lst sub )
    (if
        (and
            (setq dir (vl-string-right-trim "\\" (vl-string-translate "/" "\\" (getvar 'dwgprefix)))
                  sub (strcat dir "\\bak")
                  lst (vl-directory-files dir "*.bak" 1)
            )
            (or (vl-file-directory-p sub)
                (vl-mkdir sub)
            )
            (setq lst
                (vl-remove nil
                    (mapcar
                       '(lambda ( bak )
                            (vl-file-rename
                                (strcat dir "\\" bak)
                                (strcat sub "\\" bak)
                            )
                        )
                        lst
                    )
                )
            )
        )
        (prompt (strcat "\n" (itoa (length lst)) " bak file(s) moved to " sub))
        (prompt "\nNo bak files found in working directory.")
    )
    (princ)
)
Message 4 of 25
Lee_Mac
in reply to: Lee_Mac

Or this may be better:

 

(defun c:baksub ( / dir lst sub )
    (if
        (and
            (setq dir (vl-string-right-trim "\\" (vl-string-translate "/" "\\" (getvar 'dwgprefix)))
                  sub (strcat dir "\\bak")
                  lst (vl-directory-files dir "*.bak" 1)
            )
            (or (vl-file-directory-p sub)
                (vl-mkdir sub)
            )
        )
        (prompt
            (strcat "\n"
                (itoa
                    (length
                        (vl-remove nil
                            (mapcar
                               '(lambda ( bak )
                                    (vl-file-rename
                                        (strcat dir "\\" bak)
                                        (strcat sub "\\" bak)
                                    )
                                )
                                lst
                            )
                        )
                    )
                )
                " of "
                (itoa (length lst))
                " bak file(s) moved to " sub
            )
        )
        (prompt "\nNo bak files found in working directory.")
    )
    (princ)
)
Message 5 of 25
gilsonrss
in reply to: gilsonrss

Replace function move_bak_file by

(defun move_bak_file (path / temp_name temp_path dir_bak)
(setq temp_name (vl-filename-base path))
(setq temp_path (vl-filename-directory path))
;Check to dir bak exists
(if (not (setq dir_bak (vl-directory-files temp_path "bak" -1)))
(if (not (vl-mkdir (strcat temp_path "\\bak")))
(progn
(alert "\nError: Error to creat dir bak")
(exit)
)
)
)
(setq dir_bak (strcat temp_path "\\bak\\"))
;Delete bak old
(vl-file-delete (strcat dir_bak temp_name))

(if (not (vl-file-rename path (strcat dir_bak temp_name ".bak")))
(progn
(alert "\nError: Error to move file bak")
(exit)
)
)
)
Message 6 of 25
Klingi162
in reply to: Lee_Mac

Hey Lee,

thanks for your prompt reply to my issue. works great...as usual. 😉

Now I was wondering if there is also a way that it moves the .bak files every time I save the file without using any command? Is this even possible with lisps?

 

many thanks also to the other guys, I'm always impressed how many helpful people are on this platform. Smiley Happy

 

Message 7 of 25
Lee_Mac
in reply to: Klingi162


@Klingi162 wrote:

Hey Lee,

thanks for your prompt reply to my issue. works great...as usual. 😉


Excellent - you're welcome!


@Klingi162 wrote:

Now I was wondering if there is also a way that it moves the .bak files every time I save the file without using any command? Is this even possible with lisps?


Yes, this is possile using a Command Reactor to evaluate the function following the SAVE / SAVEAS / QSAVE commands, however, rather than have a reactor running in the background to monitor every command invoked by the user, a far cleaner solution would be to simply evaluate the function from the acaddoc.lsp to clean up any bak files when a drawing is opened.

 

For this, just copy the code to your acaddoc.lsp and add:

 

(c:baksub)

 

After the last closing parenthesis.

 

Lee

 

Message 8 of 25
Klingi162
in reply to: Lee_Mac

I'm more and more impressed every day! I just tried it and it works great. Smiley Happy

the only thing is, that I now manualy have to put it to every users acaddoc.lsp file, right?

or is there a way to change their default location to a directory on the server, if this is useful?

 

what do I have to do, if I want to put a row of comands to the "acaddoc.lsp" to load when opening a file, cause this would sometimes be useful to "force" the users computer to run certain commands. Is there a seperator between the comands or does it run them anyway if they are in this file?

 

many questions for a late saturday, hope your not to annoyed with all me requests. Smiley Embarassed

 

cheers klingi

Message 9 of 25
Lee_Mac
in reply to: Klingi162


@Klingi162 wrote:

I'm more and more impressed every day! I just tried it and it works great. Smiley Happy


 Excellent - that's great to hear Klingi Smiley Happy


@Klingi162 wrote:

the only thing is, that I now manualy have to put it to every users acaddoc.lsp file, right?

or is there a way to change their default location to a directory on the server, if this is useful?


If the acaddoc.lsp resides in a local Support File Search Path (henceforth referred to as 'SFSP'), then yes, you would need to create/modify the acaddoc.lsp for every user. However, if you were to add a new SFSP referencing a shared network path for every user, you could place the acaddoc.lsp in this network location for it to be loaded for every user.

 

Then, any modifications to the acaddoc.lsp would automatically be applied for every user with a SFSP pointing to the network location (assuming that the user does not have another acaddoc.lsp residing in a SFSP above the network location in the list of SFSPs).

 

I also discuss this in my post here.


@Klingi162 wrote:

what do I have to do, if I want to put a row of comands to the "acaddoc.lsp" to load when opening a file, cause this would sometimes be useful to "force" the users computer to run certain commands. Is there a seperator between the comands or does it run them anyway if they are in this file?


The acaddoc.lsp is just like any other AutoLISP file - AutoCAD simply loads any LISP file found with the filename acaddoc.lsp, there is nothing special about the file format or content. Therefore, you would treat the content of the acaddoc.lsp like you would with any other LISP file.

 

Lee

Message 10 of 25
Klingi162
in reply to: Lee_Mac

Well, that sounds exactly what I was looking for. I also read your other posts about this issue and found it more than informative. especially the one about acaddoc.lsp  Smiley Happy

Thanks for all the infos Lee. I will give it a try when I'm back in my office.

 

The only thing I'm still worried about, is the connecting of more than one lisp command in one file:

Do I have to use 

(c:comand_a)

 at the end of every code and 

(defun c:comand_b)

to start a new code in the same file? Smiley Frustrated

Message 11 of 25
Lee_Mac
in reply to: Klingi162


@Klingi162 wrote:

Well, that sounds exactly what I was looking for. I also read your other posts about this issue and found it more than informative. especially the one about acaddoc.lsp  Smiley Happy

Thanks for all the infos Lee. I will give it a try when I'm back in my office.


Thank you - I'm glad that my explanations are clear Smiley Happy

I hope all goes well in your tests.


@Klingi162 wrote:

 

Do I have to use 

(c:comand_a)

 at the end of every code and 

(defun c:comand_b)

to start a new code in the same file? Smiley Frustrated


Put simply, the defun expression defines the function, which can then be evaluated just like any other AutoLISP function, such as (princ) for example. The c: prefix just allows the function to be called directly from the AutoCAD command-line, without using the parentheses.

 

To demonstrate, we can define a simple function to print the current date & time:

 

(defun printdatetime ( )
    (princ (strcat "\n" (menucmd "m=$(edtime,0,dd month yyyy hh:mm:ss)")))
    (princ)
)

 

Now that the function is defined, we can evaluate it just as you would any other AutoLISP function to print the current date & time:

 

(printdatetime)
26 January 2014 17:31:28

 

However, the function definition does not need to appear in the same file as the function evaluation - we could even type the function definition line-by-line at the command-line before evaluating the defined function. All that matters is that the function is defined before we attempt to evaluate it.

 

Hence, if we have more than one function to evaluate, providing that the required functions are defined, it does not matter the order in which we evaluate them:

 

(defun printdatetime ( )
    (princ (strcat "\n" (menucmd "m=$(edtime,0,dd month yyyy hh:mm:ss)")))
    (princ)
)

(defun printhello ( )
    (princ "\nHello world!")
    (princ)
)

(defun printmymessage ( msg )
    (princ "\n")
    (princ msg)
    (princ)
)


(printhello)
(printmymessage "The date & time is:")
(printdatetime)

 

To yield the result:

 

Hello world!
The date & time is:
26 January 2014 17:36:10

 

Message 12 of 25
Klingi162
in reply to: Lee_Mac

Pretty easy an well explaind Lee,

 

I now got a better understanding of the whole function and can try out several things with this info. Smiley Happy

great introduction for a newbie! thanks for all your help, I really appreciate the time you spent for this issue.

Till soon,

cheers Klingi

Message 13 of 25
Klingi162
in reply to: Klingi162

Hey Lee,

 

now that I just set up everything an I'm happy that it works as it should, except, that it doesn't replace any existing "bak-files" in the folder when there is one existing with the same name. Smiley Frustrated

 

Furthermore I asked myself where I could find some info about the "reactors" you mentioned earlier, because I would be very interested in how I could run some lisp (for example your Update block lisp) whenever I close a file or save it...

 

thanks for any adwise

 

Message 14 of 25
Lee_Mac
in reply to: Klingi162

The following should delete existing BAK files of the same name already present in the subfolder:

 

(defun c:baksub ( / dir lst sub )
    (if
        (and
            (setq dir (vl-string-right-trim "\\" (vl-string-translate "/" "\\" (getvar 'dwgprefix)))
                  sub (strcat dir "\\bak")
                  lst (vl-directory-files dir "*.bak" 1)
            )
            (or (vl-file-directory-p sub)
                (vl-mkdir sub)
            )
        )
        (prompt
            (strcat "\n"
                (itoa
                    (length
                        (vl-remove nil
                            (mapcar
                               '(lambda ( bak / new )
                                    (if (findfile (setq new (strcat sub "\\" bak)))
                                        (vl-file-delete new)
                                    )
                                    (vl-file-rename (strcat dir "\\" bak) new)
                                )
                                lst
                            )
                        )
                    )
                )
                " of "
                (itoa (length lst))
                " bak file(s) moved to " sub
            )
        )
        (prompt "\nNo bak files found in working directory.")
    )
    (princ)
)

 

As for reactors, see this post.

 

Lee

Message 15 of 25
Klingi162
in reply to: Lee_Mac

awesome! Smiley Happy

No it cleans everything and puts it in the right folder! You made my day again! Smiley Very Happy

 

cheers Klingi

Message 16 of 25
Lee_Mac
in reply to: Klingi162

Excellent - you're most welcome Smiley Happy

Message 17 of 25
jesse.russell
in reply to: Lee_Mac

I'm fairly new to LISP and could use some specific help.

 

The solution provided has been most helpful with managing our BAK files.  I have noticed a problem that I'm having, using this allows any user to basically steal the BAK files from the network location.  We usually have anywere from 3 to 8 drafters working in the same project directory and I want to avoid running into issues with file read/write access or just flat stealing all BAKs and storing them on one user's hard drive.

 

I'd like to modify this to move the BAK file for just the current drawing to a specified location on that user's C: drive.  After applying your original code and getting it to work, I realized the problem we'd have and then started tinkering with it to make it work.  I've been pretty unsuccessful so far.

 

Any help would be most appreciated.

Message 18 of 25
Lee_Mac
in reply to: jesse.russell

jesse.russell wrote:

I'd like to modify this to move the BAK file for just the current drawing to a specified location on that user's C: drive.

 

Try the following, change the directory to suit:

 

(defun c:baksub ( / bak new sub )

    (setq sub "C:\\bak files" ;; Location for bak files
          sub (vl-string-right-trim "\\" (vl-string-translate "/" "\\" sub))
    )
    (if (and (findfile (setq bak (strcat (getvar 'dwgprefix) (vl-filename-base (getvar 'dwgname)) ".bak")))
             (or (vl-file-directory-p sub)
                 (vl-mkdir sub)
             )
        )
        (progn
            (if (findfile (setq new (strcat sub "\\" (vl-filename-base bak) ".bak")))
                (vl-file-delete new)
            )
            (vl-file-rename bak new)
            (prompt (strcat "\n" (vl-filename-base bak) ".bak moved to " new))
        )
        (prompt (strcat "\n" (vl-filename-base bak) ".bak not found."))
    )
    (princ)
)
Message 19 of 25
jesse.russell
in reply to: Lee_Mac

That worked perfectly!  Thank you!

 

I have run into a new issue, with our workflow utilizing a replication service the BAK files are not generated instantly and ready to be moved.

 

if I may ask, could you help me to revise this to now copy the current DWG and then rename it to BAK still using the same structure? It would need the ability to overwrite the current BAK file if one exists.

 

Again thanks, you do some excellent work!

Message 20 of 25
Lee_Mac
in reply to: jesse.russell

jesse.russell wrote:

That worked perfectly!  Thank you!

 

I have run into a new issue, with our workflow utilizing a replication service the BAK files are not generated instantly and ready to be moved.

 

if I may ask, could you help me to revise this to now copy the current DWG and then rename it to BAK still using the same structure? It would need the ability to overwrite the current BAK file if one exists.

 

Again thanks, you do some excellent work!

 

Thank you for your compliment Jesse, I'm glad you liked the code.

 

For your new issue, please try the following code:

 

(defun c:baksub ( / new sub )

    (setq sub "C:\\bak files" ;; Location for bak files
          sub (vl-string-right-trim "\\" (vl-string-translate "/" "\\" sub))
    )
    (if (or (vl-file-directory-p sub) (vl-mkdir sub))
        (progn
            (if (findfile (setq new (strcat sub "\\" (vl-filename-base (getvar 'dwgname)) ".bak")))
                (vl-file-delete new)
            )
            (vl-file-copy (strcat (getvar 'dwgprefix) (getvar 'dwgname)) new)
            (prompt (strcat "\nCreated " new))
        )
        (prompt (strcat "\n\"" sub "\" could not be created."))
    )
    (princ)
)

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost