Need help testing and improving my lisp

Need help testing and improving my lisp

roland.r71
Collaborator Collaborator
5,347 Views
44 Replies
Message 1 of 45

Need help testing and improving my lisp

roland.r71
Collaborator
Collaborator

Hi guys,

 

Attached you will find my MFT.lsp, which stands for "Multiple Filehandling Tool"

It allows to select files (*.dwg / *.dxf), in pretty much any way thinkable.

& to suply a lisp (*.lsp) to be loaded and/or commands to be executed, on each file.

MFT Main dialogMFT Main dialog

The idea is to share this with anybody who needs to process multiple DWG's (or DXF's).

& Its supposed to work on any version of ACAD, in combination with DOSlib.

...but I can only test it on 2014 (64bit) & 2015 (64bit)

...and the code can surely be improved in many ways. (which comes with a ton of comments)

 

& thats what I need you guys for.

Any version you can test it on, any bug you find, any improvement you can make, any suggestion you have: Bring it on! (& make this a tool everybody wants Smiley Wink)

 

Note: the command part is an addition I stuck in recently and still need to work out a bit.

The idea was to create a script & load that with each drawing, but that doesn't work.

So I changed it to an (eval ...), which works with the example you see inside the screenshot above, but I didn't yet test it with multiple lines and/or script like commands (e.g: "Zoom e" instead of "(command "zoom" "e")")

 

I might just reduce the option to a single line of code, if it turns out to difficult to allow for more. (& if you put 'garbage' in, you will get garbage out during processing, so be carefull with that option)

 

It comes with a ini file & dcl for the main dialog.

I've used "C:/Lisp/MFT/" to put the files in & it uses a subdirectory "DATA" for saving a list of files and a .scr file to hold the commands. It doesn't check or create it, so if not there, nothing will be saved/loaded for those two files/options.

You should be able to put it anywhere, just edit the path inside the .lsp INIT section

   (setq MFT_files "c:/Lisp/MFT/")

 

Where you might also set a path to find DOSlib. (It will try to find it within support path first)

   (setq DLpath "C:/Lisp/DOSLIB/")

5,348 Views
44 Replies
Replies (44)
Message 2 of 45

roland.r71
Collaborator
Collaborator

For some reason I can't attach the MFT.ini file ...

So here it is as code:

; ==============================================================================
;                        *** AutoCAD MFT v3.0 BETA ***
;                 Copyleft ;) 2004-2018 | Roland Rothenhöfer
; ==============================================================================
; Configuration file for Multiple Filehandling Tool (MFT)

; ------------------------------------------------------------------------------
[config]
; ------------------------------------------------------------------------------
; Last used *.lsp file, to run on selection
; STRING : [Drive: | //Network]/path/to/file.ext
lispFile=C:/Lisp/RR/ZA.lsp

; logfile for skipped files
; STRING : [Drive: | //Network]/path/to/file.ext
logFile=C:/Lisp/MFT/MFT_log.csv

; Last used directory to add file(s)
; STRING : [Drive: | Network]\path\to\files\
lastdir=C:/EigenData/Proj2PDF/

; Last used directory to add files in directory (tree)
; STRING : [Drive: | \\Network]\path\to\files\
userpath=C:\EigenData\Tekeningen\

; Show progression bar
; BOOLEAN : 0 = no, 1 = yes
progBar=1

; log skipped filenames
; BOOLEAN : 0 = no, 1 = yes
logSkip=1

; load LISP file
; BOOLEAN : 0 = no, 1 = yes
loadLisp=0

; load SCR file
; BOOLEAN : 0 = no, 1 = yes
loadScr=1

; warn user when file not found
; BOOLEAN : 0 = no, 1 = yes
warn_notfound=1

; warn user when file open (network)
; BOOLEAN : 0 = no, 1 = yes
warn_fileopen=1

; warn user when file Read-Only
; BOOLEAN : 0 = no, 1 = yes
warn_readonly=1

; don't open files (as) read-only
; BOOLEAN : 0 = no, 1 = yes
skip_readonly=0

; don't save changes to file
; BOOLEAN : 0 = no, 1 = yes
skip_savefile=0

; DOS style wildcard for filenames, when adding files in directory (tree)
; STRING : DOS style filename filter. *=all files ( with the extension : .DWG and/or .DXF )
wildcard=*

; Whether to include files inside sub-directories
; BOOLEAN : 0 = no, 1 = yes
recursive=0

; Whether to automatically order files (alphanumeric)
; BOOLEAN : 0 = no, 1 = yes
autosort=0

; Whether to "remember" the list. This will save the list on exit to DATA\scrGenFiles.lst
; the next time scrGenFiles is called, this list will be (re)loaded
; BOOLEAN : 0 = no, 1 = yes
autosave=1

; Whether to allow duplicate (2 or more times the same) file names
; BOOLEAN : 0 = no, 1 = yes
noDuplicate=1

; Whether to allow '_recover' files
; BOOLEAN : 0 = no, 1 = yes
noRecover=1

; Which filetype(s) to include
; INTEGER : 1 = DWG, 2 = DXF, 3 = Both
filetype=1

; Initial Single Document Mode
; BOOLEAN : 0 = off, 1 = on
SDI =0

; Initial FILEDIA mode
; BOOLEAN : 0 = off, 1 = on
FILEDIA =1
0 Likes
Message 3 of 45

roland.r71
Collaborator
Collaborator

Here's an updated version, taking care of the fresh install/1st run/missing files problems.

- All defaults are correctly set, so it can run without ini (but not save changed settings)

- Checks if path is properly set.

- Checks for dcl file.

- Checks for MFT_data directory & creates it if needed.

- Should exit properly with either the drawing active at startup, or a new blank one.

- Moved ini file to MFT_data directory, as it needs to be able to be a user specific location if its used on a network.

0 Likes
Message 4 of 45

john.uhden
Mentor
Mentor

That's quite an undertaking.  Of course you realize that makes you an undertaker.  😕

Just looking at the DCL, I'm wondering (i.e writing without testing) if the commands could be constructed much as a script is, except that at run time you convert them.  This method would require each command string to be separated by semicolons where a keyboard Enter or Space takes place.

For example:

Command: (setq str "layer;m;ABC;C;2;;lt;hidden;;")
"layer;m;ABC;C;2;;lt;hidden;;"

Command: (setq lst (@str2list str ";"))
("layer" "m" "ABC" "C" "2" "" "lt" "hidden" "" "")

Command: (eval (apply 'command lst))

Of course that method treats everything as a string, whereas some command strings might require numeric entries.

But maybe the format could require that numeric strings be prefixed with the # character and that the @str2list function converts those to 'REALs or 'INTS depending on the presence of a decimal point, or maybe by the distof function.  Plus it would have to treat contents within parentheses literally, I guess, as one string.  But that's what we're here for, right?  I'll be glad to handle that part.

 

BTW, why isn't the drawing list in a list_box?  The length of the list can exceed its height.

 

 

Mmmm. this Svedka clementine vodka tastes really good.  😕

John F. Uhden

0 Likes
Message 5 of 45

john.uhden
Mentor
Mentor
(defun @numerify (str)
  (cond
    ((wcmatch str "`##,`###,`####,`######")
      (atoi (substr str 2))
    )
    ((wcmatch str "`##'*,`###'*,`####'*,`#####'*")
      (distof (substr str 2) 4)
    )
    ((wcmatch str "`##*")
      (distof (substr str 2))
    )
    ((= (strcase str) "#PI")
      (read (substr str 2))
    )
    (1 str)
  )
)
Example:
Command: (mapcar '@numerify '("kjsdlkj" "#123" "#23'4.5" "#245.67" "#pi"))
("kjsdlkj" 123 280.5 245.67 PI)

John F. Uhden

0 Likes
Message 6 of 45

roland.r71
Collaborator
Collaborator

@john.uhden wrote:

That's quite an undertaking.  Of course you realize that makes you an undertaker.  😕

Just looking at the DCL, I'm wondering (i.e writing without testing) if the commands could be constructed much as a script is, except that at run time you convert them.  This method would require each command string to be separated by semicolons where a keyboard Enter or Space takes place.

For example:

Command: (setq str "layer;m;ABC;C;2;;lt;hidden;;")
"layer;m;ABC;C;2;;lt;hidden;;"

Command: (setq lst (@str2list str ";"))
("layer" "m" "ABC" "C" "2" "" "lt" "hidden" "" "")

Command: (eval (apply 'command lst))

Of course that method treats everything as a string, whereas some command strings might require numeric entries.

@Anonymous maybe the format could require that numeric strings be prefixed with the # character and that the @str2list function converts those to 'REALs or 'INTS depending on the presence of a decimal point, or maybe by the distof function.  Plus it would have to treat contents within parentheses literally, I guess, as one string.  But that's what we're here for, right?  I'll be glad to handle that part.

 

BTW, why isn't the drawing list in a list_box?  The length of the list can exceed its height.

 

 

Mmmm. this Svedka clementine vodka tastes really good.  😕


@Thanx for the feedback & ideas. I'll check it out later (as I'm @ work at the mo)

 

Lucky for me a straight translation (by word, not meaning) to Dutch (undertaker = ondernemer) would make that an "entrepreneur" instead of "gravedigger" Smiley Wink

 

There was no list_box for a few reasons, one being the size of the main dialog, another being about editing the list. But I might as wel put one in there. Just found some LM: stuff that might even help to make it functional & that would make the current [edit] button under "File List Options" obsolete, but that would mean even more buttons on the main dialog. (which could be better I think, but I'm out of inspiration for the layout)

 

I did a quick hack to see how it could look (but apparently I can't pass the MFT_filelist as it is, so its empty for the moment):

MFT.jpg

0 Likes
Message 7 of 45

roland.r71
Collaborator
Collaborator

I updated the function to generate the MFT.ini, if it isn't there yet.

This will also make sure the function & ini file match, as I noticed the one I posted is already "old"

The SDI & FILEDIA settings no longer get logged (FILEDIA wasn't used anymore & as its not running with a generated script anymore, there's no need to store the SDI inside the ini) & two new settings where introduced. (these two can cause a crash if using the old ini (With previous version of the function))

 

The generated version doesn't have any comments explaining each setting though. Just the key=values.

 

 

0 Likes
Message 8 of 45

john.uhden
Mentor
Mentor

Unless you are going to grab the thumbnail view somehow, I think that "File list preview" should be just "File List."  Besides, I was thinking that the file list could be just say 3 high and not take up all that vertical space.  C'mon, entrepreneurs thrive on inspiration and "work" is highly overrated, though it pays for my gas to get here.

John F. Uhden

0 Likes
Message 9 of 45

roland.r71
Collaborator
Collaborator

I've just solved a rather annoying bug involving SDI & FILETAB.

I noticed I frequently lost my tabs during tests & I noticed a FILETABCLOSE command being given (although I do no such thing inside the function, but it seems SDI does, without restoring it.)

 

So, I check the FILETABSTATE at startup, for ACAD2014 and up, and issue a FILETAB command at the end if the initial state was 1.

 

This should restore the file tabs, if they where active.

0 Likes
Message 10 of 45

Anonymous
Not applicable

I keep getting this error...

 

Command: MFT
ERROR: Couldn't locate ( C:/Lisp/DOSLIB/ ) doslib21x64.arxno function definition: DOS_GETPROGRESS

 

I created the file structure as you have

0 Likes
Message 11 of 45

john.uhden
Mentor
Mentor

You need to download and install the appropriate DOSLIB.  Just Google it and select the applicable version for your AutoCAD release.

John F. Uhden

0 Likes
Message 12 of 45

Anonymous
Not applicable

Got it!

0 Likes
Message 13 of 45

roland.r71
Collaborator
Collaborator

@john.uhden wrote:

You need to download and install the appropriate DOSLIB.  Just Google it and select the applicable version for your AutoCAD release.


 

There is that, and I do thank @Anonymous for reporting the issue, since it should warn & exit nicely. So I made some adjustments.

 

Here's the latest version, including a few other small bugfixes (like the filetab thing)

 

EDIT:

A working version this time Smiley Tongue

Message 14 of 45

roland.r71
Collaborator
Collaborator

$%^^$%#

I see I forgot I'm working on 2014 at the moment...

For the *error* function it should be (command-s "FILETAB")

For acad 2015 & up...

 

So gimmi a sec....

 

edit:

Inside the *error* function, change:

      (if ftabstate (command "FILETAB"))

into:

      (if ftabstate
         (if (< (atoi (substr (getvar "acadver") 1 2)) 20)
            (command "FILETAB")
            (command-s "FILETAB")
         )
      )
0 Likes
Message 15 of 45

roland.r71
Collaborator
Collaborator

@john.uhdenI just took a good look at the code you posted & love it!

As you might have missed, by only looking at the dialog, is that behind the edit button there is another dialog, for entering the code. the import button allows for importing .txt files or any ascii based file. that includes .scr files.

 

This one:

MFT-editscr.jpg

 

The doslib function used for this, takes & returns a single string, using \n

The line as you see it inside the main dialog is actually a copy where each \n was substituted by a space.

...so its already 'opperating' among the same lines as your idea.

 

If this could be somehow implemented to make the code for (simple) scripts like I used here in the example work, that would be awesome.

 

edit:

BTW it handles any \n inside strings ( so: "\n..." remains correct)

0 Likes
Message 16 of 45

Anonymous
Not applicable

I tried running a script I have on some drawings. 

 

Script:

^C^C_-LAYER;S;0;;_-AUDIT;Y;-PURGE;A;;N;;R;;N;_ZOOM;E;;.9X;_QSAVE;(ALERT(STRCAT"DRAWING SAVED...YOU MAY ExIT"))

 

I have to run this regularly to keep our drawings clean and improve functionality.  I used MFT to run this script on 4 files and it locked up once the final one was done processing.  I'm using AutoCAD Mechanical 2017.

 

It would also be beneficial if during your .dwg file selection, you could select a folder including subfolders.  I have a large library to maintain and this would help me audit the drawings.

0 Likes
Message 17 of 45

john.uhden
Mentor
Mentor
The idea is to give me some "simple" scripts to convert to use in a command
function, if that is required. I really never run scripts except for what
you might find in a .mnu file. Yes, I am still that ancient, but hopefully
will soon get new software to catch up to you wizards.
I think I will rename the @numerify function to the @codify function to
include handling lists within the input string, e.g. "(setvar 'osmode 0)."

John F. Uhden

0 Likes
Message 18 of 45

cadffm
Consultant
Consultant
Thats not a script and not a lisp, thats a menumacro.
You have to re-write that in script syntax.
-Purge
All
*
No

Or lisp (command "-purge" "all" "*" "no)

And check the dir button, also recursive button
I didn't test the recursive and i don't look into the code, but i think...

Sebastian

0 Likes
Message 19 of 45

john.uhden
Mentor
Mentor

Thank you, Sebastian, for providing that distinction.

As it is right now, my mind is sort of hung up on creating lisp constructs, which may well be the wrong direction, but it's fun trying.

John F. Uhden

0 Likes
Message 20 of 45

cadffm
Consultant
Consultant
Ha,
I answered to mrushcadtech only, and now i see that you working on a translation function, funny.
(i have no time for this thread now, so i didn't read all)

I like both, menumacro converting to (command..),
also the real Script syntax and the option save the content as *.scr and to select a *.scr file
You can save your list as *.scr which works also without having/starting MFT.

In newer version (than yours) you can also start other script files from a script (command SCRIPTCALL)
So it isn't a problem to create a *.scr with lisp statements, normal commands and options (script syntax) and start other script.

But ok, thats all isn't really needed if you can save/restore the mft-settings and file list in another kind and place. Just another "stupid" way to save mft-jobs.
Just4fun

Sebastian

0 Likes